黑马程序员_多线程的创建和运行机制学习笔记

来源:互联网 发布:floyd最短路算法例题 编辑:程序博客网 时间:2024/05/22 13:04

------- android培训、java培训、期待与您交流! ----------


1、线程类的定义与运行:

1)直接继承Thread类,覆盖Run方法,eg:

/** * 继承Thread实现线程类 * @author CBY * */public class DemoThread extends Thread{//自定义线程标识private int num;DemoThread(int num) {this.num = num;}public void run() {System.out.println("Thread " + num + " Start");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread " + num + " Do");}}
验证:

/** * 验证操作 * @author CBY * */class TestMain {public static void main(String[] args) {//新建第一个线程DemoThread dt1 = new DemoThread(1);//新建第二个线程DemoThread dt2 = new DemoThread(2);//启动第一个线程dt1.start();//启动第二个线程dt2.start();}}

2)通过实现Runnable接口,并将实现后的类,入参到new Thread的构造器中,eg:

/** * 实现Runnable的类 * @author CBY * */class DemoObject implements Runnable {//自定义线程标识private int num;DemoObject(int num) {this.num = num;}public void run() {System.out.println("Thread " + num + " Start");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread " + num + " Do");}}
验证:

public static void main(String[] args) {//定义对象1DemoObject do1 = new DemoObject(1);//定义对象2DemoObject do2 = new DemoObject(2);//定义线程1,并插入对象1Thread trd1 = new Thread(do1);//定义线程2,并插入对象2Thread trd2 = new Thread(do2);//启动线程1trd1.start();//启动线程2trd2.start();}

3)如何选择以上两种方法的实现:

之前在论坛中,遇到过这个问题。把当时想法和回复贴过来。以备查找吧:

无论是实现Runnable方法,还是继承Thread类,其实都是可以的。

主要还是看对象的设计需求。

Runnable的一个例子:

比如:让设计一个动物的类继承体系,猫、狗、兔子,都继承于动物,且都有“吃”这个方法:


如果要让多只狗狗同时在“吃”,那么,多线程,显然是首选实现方式。

但JAVA的继承体系是单根的,也就是只有一个父节点。“猫”、“狗”、“兔子”都已经继承了“动物”这个父类,显然再想继承Thread是不可能的。

所以只能用Runnable接口,实现run()方法后,再交给Thread去运行。

这样的优点,就是不破坏类本身的继承体系。

也是你以后在工作中,相对于继承Thread类来说,更加优选的方案。

至于继承Thread类,如果确定这个类本身就是一个线程类,那直接继承Thread是完全可以的。


2、线程的运行状态即状态转换:(如图)



3、线程安全(synchronized):

同步函数:

对象的同步函数的锁是对象this。

类的同步函数的锁是类字节码。

eg:

//同步函数@Overridepublic synchronized void run() {while(ticketNum>0){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();System.out.println(Thread.currentThread().getName() + ":" + ticketNum--);}}
同步代码块:

需要定义指定传入的同步锁。

eg:

//同步代码块@Overridepublic void run() {synchronized(this){while(ticketNum>0){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":" + ticketNum--);}}}

同步于非同步方法

当一个同步代码函数的锁,被一个非同步函数访问,并修改时。
非同步函数的运行将不受同步函数的影响。


死锁

通常死锁的出现时同步中嵌套同步,而锁却不同。




------- android培训、java培训、期待与您交流! ----------

0 0
原创粉丝点击