废话不多说,看线程状态先从源码定义看起
public enum State {
//初始
NEW,
//运行
RUNNABLE,
//阻塞
BLOCKED,
//等待
WAITING,
//超时等待
TIMED_WAITING,
//终止
TERMINATED;
}
可以通过下面代码获取线程状态:
Thread.State state = thread.getState();
一、线程状态说明
-
NEW(初始):初始状态,线程被创建,但是还没有调用start方法开启线程,此时为初始状态。
-
RUNNABLE(运行):运行状态分为两种:一种是就绪状态,另一种是运行状态,一旦线程开启调用start()方法,则此线程进入JVM中,等待CPU调度,与其他的线程同时抢占CPU使用权,抢到CPU资源的线程转换到运行状态!
-
BLOCKED(阻塞):阻塞状态是线程进入synchronized修饰的同步方法和同步代码块或者被lock加锁的方法,被其他线程抢先占用锁使用,且未释放锁时,进入阻塞状态。等待锁释放时,重新进入就绪状态。
-
WAITING(等待):
-
线程通过调用wait()方法进入线程等待状态,等待其他线程notify()唤醒!
-
通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
-
TIMED_WAITING(超时等待):处于这种状态的线程不会抢占CPU执行,不用无限等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
-
TERMINATED(终止):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。不能调用第二次start!
二、线程状态图
转自:https://blog.csdn.net/pange1991/article/details/53860651博主的图,画的值得学习
三、线程状态方法
1、线程休眠-sleep
- 模拟网络延时:放大问题的发生性
- sleep时间达到后线程进入就绪状态;
- 每一个对象都有一个锁,sleep不会释放锁;
- 传入休眠时间,本地方法接口调用本地方法库,扩展java的使用。
public static native void sleep(long millis) throws InterruptedException;
2、线程礼让-yield
-
让当前正在执行的线程暂停,但不阻塞
-
将线程从运行状态转为就绪状态
-
让cpu重新调度,礼让不一定成功!看CPU心情
-
本地方法接口调用本地方法库,扩展java的使用。
public static native void yield();
3、线程强制-jion
-
只会使主线程进入等待池并等待线程执行完毕后才会被唤醒。
-
并不影响同一时刻处在运行状态的其他线程。
-
jion方法是一个同步方法基于wait方法实现的!(可查看源码清晰得出)
4、线程等待-wait
- 线程调用wait()方法, 表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
- 依靠notify()/notifyAll()唤醒或者wait(long timeout) timeout时间到自动唤醒。
- 也是一个本地方法
5、线程唤醒-notify
-
唤醒在此对象监视器上等待的单个线程,选择是任意性的。
-
notifyAll()唤醒在此对象监视器上等待的所有线程。
-
也是一个本地方法