线程的五态
新建态(New)
使用关键词new创建一个Thread对象,通过start()方进入Runnable状态
就绪态(Runnable)
调用start()方法在JVM中创建新线程,只能进入Running或意外终止
运行态(Running)
可直接进入terminated,如调用JDK已经不推荐使用的stop方法
可进入blocked,如调用sleep或wait方法
可进入某阻塞IO操作
可获取某个锁资源
由于CPU调度器轮询,该线程放弃执行,进入Runnable
主动调用yield方法,放弃CPU执行权,进入Runnable
阻塞态(Blocked)
可直接进入Terminated
线程阻塞的操作操作结束,进入Runnable
完成指定时间的休眠(sleep),进入Runnable
处于wait中的线程被notify/notifyall唤醒,进入Runnable
线程获取到锁资源,进入Runnable
线程在阻塞过程中被打断,如其他线程调用interrupt方法,进入Runnable
终止态(Terminated)
线程正常结束
线程运行出错,意外结束
JVM Crash导致所有线程结束
流程图
线程五态流转.png
线程start()
在进行new Thread().start()的过程中,start()方法在内部调用start0()方法,同时,start0()调用新线程的run()方法
同一个线程不能启动两次(start),否则就会报异常
线程启动后将被加入到一个Thread Group中
一个线程生命周期结束,也就是到了终止态,不能再次被启动(start)
Thread类
在JDK中代表线程的就只有Thread类
所谓的创建新线程有两种方式的说法不严谨
实际是实现线程执行带院的方式有两种
1. 重写Thread的run()方法
2. 实现Runnable接口的run()方法,并将Runnable实例用作构造Thread的参数
Thread类的run()方法不能共享,Runnable实例的run()方法可以
Thread类:
class TestThread extends Thread {
int static SUM=50;
@Override
public void run(){
//实际执行逻辑
};
};
new TestThread("一号").start();
new TestThread("二号").start();
//两个线程是不同的Thread对象
//两个线程共享由static修饰的变量SUM
Runnable接口:
class TestRunnable implements Runnable {
int MAX=30;
@Override
public void run() {
//实际执行逻辑
};
};
TestRunnable tr = new TestRunnable();
new Thread(tr,"三号");
new Thread(tr,"四号");
//三号与四号线程共享同一个Runnable对象
//变量MAX由两个线程共享,无需static修饰
两种方式都是运行Thread运行run()方法,只不过第二种将Runnable对象作为参数传给Thread,Thread调用Runnable的run()方法