JAVA线程状态
1. 基础的线程状态
Thread源码状态定义:
public static enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
private State() {
}
}
- 初始化状态(NEW)
- 运行状态(RUNNABLE和RUNNING)
- 等待(WAITING)
- 超时等待(TIMED_WAITING)
- 终止状态(TERMINATED)
- 阻塞状态(BLOCKED)
2. 线程的转换图
-
Thread New出来就是初始化状态
-
在start获取到Cpu时间片的时候是就绪状态,里面包含了运行状态
-
正常运行到结束就是终止状态(Terminated)
-
当线程运行过程中遇到
wait()
,join()
,LockSupport.park(Thread)
变为等待状态,需要对应notify()
,notifyAll()
,LockSupport.unpark(Thread)
来解除回到就绪状态 -
当遇到带有超时时间的方法块时候就到了超时等待状态,
wait(Long)
,join(Long)
,LockSupport.park(Long)
,也需要对应的方法来接触回到就绪状态 -
方法遇到
sychronized
的方法块的时候就会进入阻塞状态Note:使用
concurrent.lock
下面的方法时候会进入到WAITING或者是TIMED_WAITING状态,因为它会去调用LockSupport
的方法
3. 线程的操作
3.1 interrupt
当执行中断操作的时候,就是为线程打了一个标志位,表示这个线程是不是被其他线程中断过。线程可以调用isInterrupted()
来请求感知自身的中断操作。
可以通过这个标识位来控制线程结束,判断isInterrupted()
来优雅的停止线程。
3.2 join
join是一个线程协作的模型,一个线程依赖于另外一个线程的输出。在一个实例线程中ThreadA
中执行threadB.join();
含义就是会等待threadB
执行完threadA
才会继续执行。
public class JoinDemoTest {
public static void main(String[] args) {
// CyclicBarrier cyclicBarrier = new CyclicBarrier();
Thread threadA = new Thread(
() -> {
try {
System.out.println(Thread.currentThread().getName() + " start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
);
Thread threadB = new Thread(
() -> {
try {
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " start");
System.out.println(Thread.currentThread().getName() + " end");
}
);
threadA.start();
threadB.start();
}
}
结果:
Thread-0 start
Thread-0 end
Thread-1 start
Thread-1 end
3.3 sleep
会让线程休眠一段时间。
sleep和wait的主要区别点
- sleep不会失去CPU的资源,在过了一段时间以后还是会继续执行的,wait必须等待notify或者notifyAll通知才能继续执行,并且还需再次获取CPU的时间片
- sleep是Thread的静态方法,wait是Object的实例方法
- wait需要在Sychronized的方法块中使用,sleep没有这种限制
3.4 yield
yield是一个静态方法,执行会让出CPU,等待下次竞争,如果可以就会获取CPU时间片继续执行。