Java线程的生命周期有五种状态:新建、就绪、运行、阻塞和死亡。
新建:当创建一个新的Thread实例时,该实例处于新建状态。在这个阶段,Thread实例已经创建好了,但是还没有被启动。
就绪:当调用Thread实例的start()方法时,该实例就会处于就绪状态。在这个阶段,Thread实例已经准备好被执行,但是还没有被CPU执行。
运行:当CPU开始执行Thread实例时,该实例就会处于运行状态。在这个阶段,Thread实例正在执行run()方法中的代码。
阻塞:当一个Thread实例因为某些原因而放弃CPU时间片时(如I/O请求、向其他对象发送信号或者其他原因), 该实例就会处于阻塞状态。在这个阶段, Thread实例正在等待其他条件的改变而重新回到就绪或者运行的状态。
public void run(){ // 运行中
while(true){
// do something
try{
Thread.sleep(1000); // 阻塞1s
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
死亡: 当一个Thread实例执行它的run()方法中的代码并且run()方法正常退出时, 该Thread实例就会处于死亡的生命周期中。
线程总是处于以下六种状态之一:
线程的所有这些状态都是JVM状态。
当一个线程被创建并且它的start()方法还没有被调用时,它处于新的状态。
Thread t = new MyThreadClass(); // t is in the new state
准备运行或运行的线程处于可运行状态。
如果线程尝试输入或重新输入同步的方法或块,但该监视器正在被另一个线程使用,则该线程处于阻塞状态。
线程可以通过调用下表中列出的方法将自身置于等待状态。
方法 | 描述 |
---|---|
wait() | 从Object类。 |
join() | 从Thread类。 |
park() | 从java.util.concurrent.locks.LockSupport类。调用此方法的线程可以通过调用线程上的unpark()方法等待直到许可可用。 |
线程可以通过调用下表中列出的方法将自身置于等待等待状态。
描述 | 描述 |
---|---|
sleep() | 从Thread类。 |
wait (long millis) wait(long millis, int nanos) | 从Object类。 |
join(long millis) join(long millis, int nanos) | 从Thread类。 |
parkNanos (long nanos) parkNanos (Object blocker, long nanos) | 从LockSupport类,它在java.util.concurrent.locks包中。 |
parkUntil (long deadline) parkUntil (Object blocker, long nanos) | 从LockSupport类,它在java.util.concurrent.locks包中。 |
已完成其执行的线程处于终止状态。
终止的线程不能转换到任何其他状态。
我们可以使用一个线程的isAlive()方法,在它已经启动后,知道它是否存活或终止。
我们可以使用Thread类中的getState()方法来随时获取线程的状态。
此方法返回Thread.State枚举类型的常量之一。
以下代码演示了线程从一个状态到另一个状态的转换。
class ThreadState extends Thread { private boolean keepRunning = true; private boolean wait = false; private Object syncObject = null; public ThreadState(Object syncObject) { this.syncObject = syncObject; } public void run() { while (keepRunning) { synchronized (syncObject) { if (wait) { try { syncObject.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public void setKeepRunning(boolean keepRunning) { this.keepRunning = keepRunning; } public void setWait(boolean wait) { this.wait = wait; } } public class Main { public static void main(String[] args) throws InterruptedException { Object syncObject = new Object(); ThreadState ts = new ThreadState(syncObject); System.out.println("Before start()-ts.isAlive():" + ts.isAlive()); System.out.println("#1:" + ts.getState()); ts.start(); System.out.println("After start()-ts.isAlive():" + ts.isAlive()); System.out.println("#2:" + ts.getState()); ts.setWait(true); Thread.currentThread().sleep(100); synchronized (syncObject) { System.out.println("#3:" + ts.getState()); ts.setWait(false); syncObject.notifyAll(); } Thread.currentThread().sleep(2000); System.out.println("#4:" + ts.getState()); ts.setKeepRunning(false); Thread.currentThread().sleep(2000); System.out.println("#5:" + ts.getState()); System.out.println("At the end. ts.isAlive():" + ts.isAlive()); } }
上面的代码生成以下结果。
Java线程教程 -Java同步器同步器对象与一组线程一起使用。它维护一个状态,根据它的状态,它让一个线程通过或强迫它等待。本节将...
Java网络教程 -Java URL绝对URI具有以下通用格式:scheme:scheme-specific-part scheme-specific-part 取决于 scheme 。例如,ht...
Java网络教程 - Java网络UDP服务器以下代码显示了如何编写UDP回显服务器:DatagramSocket socket= new DatagramSocket(12345);Da...
JavaFX教程 -JavaFX文本另一个基本的JavaFX节点是Text节点,它允许我们在场景图上显示测试。要创建 Text 节点,请使用 javafx.sc...