Java中的线程可以处于不同的状态,包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。了解这些状态及其转换对于优化并发程序和解决并发问题非常重要。以下是详解Java的线程状态的完整攻略:
线程的状态
- NEW:创建一个线程对象,但是还没有调用start方法时,线程对象的状态是NEW。
- RUNNABLE:一旦调用start方法,线程就进入RUNNABLE状态。在这个状态下,线程可以被CPU分配时间片,执行任务。但是,需要注意的是,RUNNABLE状态下的线程可能没有获取到锁,也可能在等待某个资源,等待时间片分配,或者被其他线程阻塞。
- BLOCKED:当线程在等待获得锁、等待I/O事件完成等原因时,就会进入BLOCKED状态。在这个状态下,线程会永远等待当前需要的资源被释放。
- WAITING:当线程在等待某个其他线程通知被通知之前,可以处于WAITING状态。在这个状态下,线程是无限期等待,直到获取到通知。
- TIMED_WAITING:当线程在等待某个其他线程通知被通知之前,可以处于TIMED_WAITING状态,这个状态下线程等待一定的时间,并且会在等待超时或者获取到通知之前被唤醒。
- TERMINATED:线程运行结束后,进入TERMINATED状态。
线程状态转换
Java线程的状态可以通过调用以下方法实现:
- Thread.sleep(long millis)
- Object.wait()
- Object.wait(long timeout)
- Thread.yield()
- LockSupport.park()
- LockSupport.unpark(Thread thread)
示例1
public class ThreadStatusDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (ThreadStatusDemo.class) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("t1 state: " + t1.getState()); // NEW
t1.start();
System.out.println("t1 state: " + t1.getState()); // RUNNABLE
synchronized (ThreadStatusDemo.class) {
System.out.println("t1 state: " + t1.getState()); // BLOCKED
}
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 state: " + t1.getState()); // TERMINATED
}
}
在这个示例中,线程t1开始于NEW状态,实际上它仅被创建,没有开始运行。调用start方法后,它进入了RUNNABLE状态,准备运行。在synchronized块中获得锁的代码中,t1将进入BLOCKED状态。几秒钟后,线程结束并进入TERMINATED状态。
示例2
public class ThreadStatusDemo2 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
synchronized (ThreadStatusDemo2.class) {
try {
ThreadStatusDemo2.class.wait(); // 等待被通知
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
System.out.println("t1: " + t1.getState()); // RUNNABLE
System.out.println("t2: " + t2.getState()); // BLOCKED
try {
Thread.sleep(3000); // 等待t1和t2都得到时间片执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1: " + t1.getState()); // TERMINATED
synchronized (ThreadStatusDemo2.class) {
ThreadStatusDemo2.class.notify(); // 通知t2
}
System.out.println("t2: " + t2.getState()); // TERMINATED
}
}
在这个示例中,线程t1被创建并启动后,进入RUNNABLE状态,t2在synchronized块中等待调用notify或notifyAll方法,进入了WAITING状态。注意,使用wait方法需要获取该对象的监视器(即锁)。几秒钟后,t1结束并进入TERMINATED状态。接着,t2被通知并结束进入TERMINATED状态。
以上是详解Java的线程状态的完整攻略,理解线程状态及其转换过程是学习Java中并发编程的重要一步。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java的线程状态 - Python技术站