欢迎浏览高耳机的博客
希望我们彼此都有更好的收获
感谢三连支持!
在Java中,线程可以处于多种状态,这些状态描述了线程的生命周期。了解这些状态及其转换条件对于编写高效且无错误的多线程应用程序至关重要。本文将总结Java线程的几种状态,每种状态的含义,以及状态之间的切换条件。
线程状态的种类及含义
Java线程的状态主要有以下几种:
- 新建状态(New):线程对象已被创建,但还没有调用start()方法。
- 可运行状态(Runnable):线程已经调用了start()方法,可能正在运行,也可能正在等待CPU时间片。
- 阻塞状态(Blocked):线程因为等待监视器锁(即等待某个同步锁)而进入阻塞状态,它在等待获取该资源的锁。
- 等待状态(Waiting):线程通过调用
wait()
、join()
或者LockSupport.park()
方法进入等待状态,需要其他线程通知或中断才能返回。 - 计时等待状态(Timed Waiting):线程通过调用
sleep(long millis)
、wait(long timeout)
、join(long millis)
、LockSupport.parkNanos()}
、LockSupport.parkUntil()
等方法,进入计时等待状态,与等待状态类似,但是有最大时间限制,超过时间后会自动唤醒。 - 终止状态(Terminated):线程的run()方法执行结束,或者因异常退出了run()方法。
状态之间的切换条件
- 从新建到可运行:调用线程的
start()
方法。 - 从可运行到阻塞:线程尝试获取一个已经被其他线程持有的锁。
- 从可运行到等待:调用
wait()
、join()
或LockSupport.park()
方法。 - 从可运行到计时等待:调用
sleep(long millis)
、wait(long timeout)
、join(long millis)
、LockSupport.parkNanos()}
、LockSupport.parkUntil()
方法。 - 从等待到可运行:其他线程调用了当前线程的
notify()
或notifyAll()
方法,或者当前线程的LockSupport.unpark(Thread)
被调用。 - 从计时等待到可运行:等待时间结束,线程自动唤醒。
- 从可运行到终止:线程执行完run()方法,或者在run()方法中发生未捕获的异常。
- 从阻塞到可运行:线程成功获取到锁,锁被释放后线程可以继续执行。
以下是线程状态的转换代码示例:
- 新建到可运行(NEW -> RUNNABLE):
public class ThreadStateExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("Thread is running");
});
System.out.println("Thread state before start: " + thread.getState()); // NEW
thread.start();
System.out.println("Thread state after start: " + thread.getState()); // RUNNABLE
}
}
- 可运行到终止(RUNNABLE -> TERMINATED):
public class ThreadStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("Thread is running");
});
thread.start();
thread.join(); // 等待线程结束
System.out.println("Thread state after thread.join: " + thread.getState()); // TERMINATED
}
}
- 可运行到等待(RUNNABLE -> WAITING):
public class ThreadStateExample {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
Thread.sleep(1000); // 确保线程进入WAITING状态
System.out.println("Thread state: " + thread.getState()); // WAITING
}
}
- 可运行到计时等待(RUNNABLE -> TIMED_WAITING)
public class ThreadStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(5000); // 线程进入计时等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
Thread.sleep(1000); // 确保线程进入TIMED_WAITING状态
System.out.println("Thread state: " + thread.getState()); // TIMED_WAITING
}
}
- 可运行到阻塞(RUNNABLE -> BLOCKED):
public class ThreadStateExample {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(10000); // 持有锁并休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) { // 尝试获取已被thread1持有的锁,因此进入BLOCKED状态
// 执行相关操作
}
});
thread1.start();
Thread.sleep(1000); // 确保thread1持有锁
thread2.start();
Thread.sleep(1000); // 确保thread2尝试获取锁
System.out.println("Thread2 state: " + thread2.getState()); // BLOCKED
}
}
希望这篇博客能为你理解线程状态提供一些帮助。
如有不足之处请多多指出。
我是高耳机。