Java多线程 线程状态原理详解
介绍
Java中的线程可以并行执行多个代码块,既可提高程序执行效率,又可防止程序因某些阻塞造成“卡死”。
线程状态就是指线程在代码执行期间所处的不同运行状态,进而影响着线程的执行顺序及资源分配。在Java中,线程状态主要由以下5种状态组成:
- 新建状态(New)
- 就绪状态(Runnable)
- 阻塞状态(Blocked)
- 等待状态(Waiting)
- 死亡状态(Terminated)
下面我们将分别详细讲解这5种状态,以及这些状态间的转换关系。
新建状态(New)
当一个Thread类的实例被创建时,该实例处于新建状态(New)。此时,线程实例仅被创建,但尚未开始执行。具体代码如下:
Thread t = new Thread();
就绪状态(Runnable)
当一个线程实例被创建,且调用了start方法,此时线程将进入就绪状态(Runnable),等待执行。在该状态下,线程实例已经被加入当前进程的执行队列中,并与其他线程处于竞争状态,谁的优先级高,谁将被先执行。具体代码如下:
Thread t = new Thread();
t.start();
阻塞状态(Blocked)
线程在执行过程中,如果发现自身要访问的资源被占用,则会进入阻塞状态(Blocked)。此时,该线程将会进入“睡眠”状态,等待获取到需要访问的资源,才有可能被重新调度执行。当线程被阻塞时,会释放当前所持有的锁。以下示例代码演示阻塞状态的运行流程:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
try {
// 等待1000毫秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
synchronized (t) {
// 再次等待1000毫秒
Thread.sleep(1000);
}
// 输出BLOCKED
System.out.println(t.getState());
上述代码中,线程t被加入了一个同步代码块,并在其中等待1000毫秒。接着,主线程又获取了该同步代码块的锁,并在同步代码块中等待1000毫秒,此时t被阻塞。最后,输出t的线程状态,其状态为BLOCKED。
等待状态(Waiting)
当线程处于等待状态(Waiting)时,此时线程需要等待其他线程执行结束或者持有锁的线程释放锁。一个线程在进入等待状态后,只有等待其他线程调用notify或notifyAll方法以通知该线程才能重新调度执行。以下示例演示等待状态的运行流程:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
try {
// 进入等待状态,并释放锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
// 输出WAITING
System.out.println(t.getState());
// 等待线程被唤醒
synchronized (t) {
t.notify();
}
在上述代码中,线程t被加入了一个同步代码块,并在其中进入等待状态,并释放锁。然后,输出t的线程状态,其状态为WAITING。接着,主线程在同步代码块中唤醒了t,此时t的状态将变为RUNNABLE。
死亡状态(Terminated)
当线程执行到run方法的末尾,或者在运行过程中出现了未捕获的异常,线程将会进入死亡状态(Terminated)。此时,线程实例已经被销毁,不能再次进入其他状态。以下示例代码演示了如何让线程进入死亡状态:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread is running");
}
});
t.start();
// 让主线程等待t线程执行完毕
t.join();
// 输出TERMINATED
System.out.println(t.getState());
在上述代码中,线程t被创建并启动,然后主线程调用了t.join()方法,等待t线程执行完毕。执行完毕后,输出t的状态,其状态被修改为TERMINATED。
总结
Java中的线程状态主要有5种状态,分别是新建状态(New)、就绪状态(Runnable)、阻塞状态(Blocked)、等待状态(Waiting)和死亡状态(Terminated)。这些状态间的转换是由JVM内部自动控制的,我们只需要专注于相应的业务代码中即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程 线程状态原理详解 - Python技术站