线程状态
线程一共有6种状态。
NEW(初始状态)
RUNNABLE(可运行状态)
BLOCKED(阻塞状态)
WAITING(等待状态)
TIME_WAITING(超时等待状态)
TERMINATED(终止状态)
NEW(初始状态)
当实例化出一个线程时,此时线程状态为NEW状态。
方法一:继承Thread类
方法二:实现Runnable接口
RUNNABLE (可运行状态、就绪/运行中状态)
就绪状态: Thread.start()调用 、Thread.sleep()结束、Object.notify()调用、Object.notifyAll() 调用、Thread.yield()调用、获取对象锁
运行中状态:线程获取到CPU的使用权
BLOCKED (阻塞状态)
线程等待进入synchronized同步代码块或同步方法 —-> 获取到锁
lock?
WAITING (等待状态)
Object.wait()调用、Thread.join()调用
TIME_WAITING(超时等待状态)
Thread.sleep()调用、Object.wait(long)调用、Thread.join(long)调用
TERMINATED (终止状态)
线程run()方法执行完毕,或者主线程main()方法执行完毕,则线程终止
在一个终止的线程调用start()方法,会抛出 java.lang.IllegalThreadStateException
异常
线程状态之间的交换
NEW到RUNNABLE状态
TestThread testThread = new TestThread();
Thread thread = new Thread(testThread);
thread.start();
RUNNABLE到BLOCKED状态
public class Account {
public void draw(int aount) {
synchronized(this) {
// 伪代码
}
}
}
// 或者
public synchronized void drawMethod(int aount) {
// 伪代码
}
RUNNABLE到WAITING状态
三种场景会触发RUNNABLE到WAITING的转换:
1、获得synchronized
隐式锁的线程,调用了Object.wait()
方法;
2、调用线程同步Thread.join()
方法;
比如有一个线程对象thread A ,当调用A.join()的时候,执行这条语句的线程会等待threadA执行完,其线程状态会从RUNNABLE转换为WAITING。 当线程threadA执行完,原来等待它的线程又会从WAITING状态转换到RUNNABLE。
3、调用LockSupport.park()
方法。
Java并发包中的锁,都是基于LockSupport对象实现的。 调用LockSupport.park()方法,当前线程会阻塞,线程状态会从RUNNABLE转换到WAITING。 调用LockSupport.unpark(Thread) 方法,可唤醒目标线程,目标线程状态又会从WAITING状态转换到RUNNABLE状态。
synchronized(object) {
try {
object.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
RUNNABLE到TIME_WAITING状态
5种场景会触发RUNNABLE向TIME_WAITING转换
1、调用带超时参数的Thread.sleep(long millis)
方法;
2、获得synchronized
隐式锁的线程,调用带超时参数的Object.wait(long timeout)
方法;
3、调用带超时参数的Thread.join(long millis)
方法;
4、调用带超时参数的LockSupport.parkNanos(Object blocker, long deadline
方法;
5、调用带超时参数的LockSUpport.parkUntil(long deadline)
方法。
RUNNABLE到TERMINATED状态
2种场景触发RUNNABLE到TERMINATED状态
1、异常中断(interupt方法);
2、run方法执行完毕。