Java中如何定义线程的生命周期
本文详细介绍了Java线程的六种状态及其转换过程。线程状态包括:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超时等待)和TERMINATED(终止)。通过多个代码示例演示了不同状态间的转换场景,如通过wait()/notify()实现WAITING状态,使用sleep()进入TIMED_WAITING状态,以及同步锁导致的
一、核心
NEW(新建):
线程被创建(已经创建了Thread对象),但未启动(未调用start()方法);
RUNNABLE(可运行):
等待操作系统的其他资源(如CPU),或正在Java虚拟机中执行;
分为就绪(ready)和运行(running)两种状态;
BLOCKED(阻塞):
线程被阻塞等待监视器锁;
WAITING(等待):
线程进入等待状态,等待其他线程做出一些特定动作(通知或中断);
TIMED_WAITING(超时等待):
线程在指定的时间内等待;
TERMINATED(终止):
线程已经执行完毕(run方法已经完成)。
二、NEW→ RUNNABLE→ TERMINATED
public class ThreadLifeCycleDemo1 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
});
// 主线程打印thread1线程状态
System.out.println("thread1线程New,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
三、 BLOCKED
线程试图获取一个对象的同步锁,而该锁被其他线程持有。
public class ThreadLifeCycleDemo2 {
private static final Object lock = new Object();
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
synchronized (lock){
try {
Thread.sleep(10000); // thread1线程持有锁10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 创建thread2线程
Thread thread2 = new Thread(() -> {
// thread2线程执行run方法,打印thread2线程自己的状态
System.out.println("thread2线程Runnable,状态:" +Thread.currentThread().getState());
synchronized (lock){
System.out.println("thread2线程获得锁");
}
});
// 启动thread1线程
thread1.start();
// 主线程打印thread2线程状态
System.out.println("thread2线程NEW,状态:" + thread2.getState());
// 启动thread2线程
thread2.start();
// 主线程睡眠0.5秒,等待thread2线程启动
Thread.sleep(500);
// 主线程打印thread2线程状态
System.out.println("thread2线程BLOCKED,状态:" + thread2.getState());
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread2线程状态
System.out.println("thread2线程TERMINATED,状态:" + thread2.getState());
}
}
四、WAITING
进入WAITING状态的方法:
- Object.wait() :等待其他线程调用 notify() 或 notifyAll()
- Thread.join() :等待指定线程终止
- LockSupport.park() : 禁用当前线程进行线程调度
(一)Object.wait()
public class ThreadLifeCycleDemo3 {
private static final Object lock = new Object();
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
synchronized (lock){
try {
// 释放锁并进入WAITING状态
lock.wait();
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 创建thread2线程
Thread thread2 = new Thread(() -> {
synchronized (lock){
// 唤醒一个等待线程
lock.notify();
System.out.println("thread2唤醒一个等待线程");
}
});
// 主线程打印thread1线程状态
System.out.println("thread1线程NEW,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动并进入wait()调用
Thread.sleep(500);
// 主线程打印thread1线程状态
System.out.println("thread1线程WAITING,状态:" + thread1.getState());
// 启动thread2线程
thread2.start();
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
(二)Thread.join()
public class ThreadLifeCycleDemo4 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
try {
// 睡眠5秒,模拟任务执行
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 创建thread2线程
Thread thread2 = new Thread(() -> {
// thread2线程执行run方法,打印thread2线程自己的状态
System.out.println("thread2线程Runnable,状态:" +Thread.currentThread().getState());
try {
// 启动thread1线程
thread1.start();
// 调用join() ,thread2线程等待thread1线程执行完毕
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 主线程打印thread2线程状态
System.out.println("thread2线程NEW,状态:" + thread1.getState());
thread2.start();
// 主线程睡眠0.5秒,等待thread2启动并进入join()调用
Thread.sleep(500);
// 主线程打印thread2线程状态
System.out.println("thread2线程WAITING,状态:" + thread2.getState());
// 主线程等待thread2执行完毕
thread2.join();
// 主线程打印thread2线程状态
System.out.println("thread2线程TERMINATED,状态:" + thread2.getState());
}
}
状态变化流程:
调用 thread.join() → 进入 synchronized 块 → 调用 wait() → 进入 WAITING 状态
// Thread.join() 源码
public final void join() throws InterruptedException {
join(0);
}
// Thread.join(long millis) 源码
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
唤醒机制:
当目标线程结束时,JVM 会自动调用 notifyAll(),所有等待在该线程对象上的线程都会被唤醒。
(三)LockSupport.park()
import java.util.concurrent.locks.LockSupport;
public class ThreadLifeCycleDemo5 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
LockSupport.park();
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
});
// 创建thread2线程
Thread thread2 = new Thread(() -> {
LockSupport.unpark(thread1);
System.out.println("thread2线程唤醒thread1线程");
});
// 主线程打印thread1线程状态
System.out.println("thread1线程NEW,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动
Thread.sleep(500);
// 主线程打印thread2线程状态
System.out.println("thread1线程WAITING,状态:" + thread1.getState());
// 启动thread2线程
thread2.start();
// 主线程睡眠0.5秒,等待thread2线程启动并唤醒thread1
Thread.sleep(500);
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
五、TIMED_WAITING
进入TIMED_WAITING状态的方法:
- Object.wait(long timeout)
- Thread.join(long millis)
- Thread.sleep(long millis)
- LockSupport.parkNanos(long nanos)
- LockSupport.parkUntil(long deadline)
特征:
在指定的时间内等待。
时间到后自动唤醒,无需其他线程干预。
(一)Object.wait(long timeout)
public class ThreadLifeCycleDemo6 {
private static final Object lock = new Object();
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
synchronized (lock){
try {
// thread1进入TIMED_WAITING状态3秒
lock.wait(3000);
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 主线程打印thread1线程状态
System.out.println("thread1线程New,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动,执行wait()
Thread.sleep(500);
// 主线程打印thread1线程状态
System.out.println("thread1线程TIMED_WAITING,状态:" + thread1.getState());
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
(二)Thread.join(long millis)
参考WAITING的Thread.join()
(三)Thread.sleep(long millis)
public class ThreadLifeCycleDemo7 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
try {
// thread1进入TIMED_WAITING状态3秒
Thread.sleep(3000);
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 主线程打印thread1线程状态
System.out.println("thread1线程New,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动,执行sleep()
Thread.sleep(500);
// 主线程打印thread1线程状态
System.out.println("thread1线程TIMED_WAITING,状态:" + thread1.getState());
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
(四)LockSupport.parkNanos(long nanos)
import java.util.concurrent.locks.LockSupport;
public class ThreadLifeCycleDemo8 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
// thread1暂停3秒(3,000,000,000 纳秒 = 3秒)
LockSupport.parkNanos(3000000000L);
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
});
// 主线程打印thread1线程状态
System.out.println("thread1线程New,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动,执行LockSupport.parkNanos()
Thread.sleep(500);
// 主线程打印thread1线程状态
System.out.println("thread1线程TIMED_WAITING,状态:" + thread1.getState());
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
(五)LockSupport.parkUntil(long deadline)
import java.util.concurrent.locks.LockSupport;
public class ThreadLifeCycleDemo9 {
public static void main(String[] args) throws Exception{
// 创建thread1线程
Thread thread1 = new Thread(() -> {
// thread1线程执行run方法,打印thread1线程自己的状态
System.out.println("thread1线程Runnable,状态:" +Thread.currentThread().getState());
// 暂停直到指定时间点(3秒后的时间戳(从1970年以来的毫秒数))
LockSupport.parkUntil(System.currentTimeMillis() + 3000);
// 唤醒后
System.out.println("唤醒后thread1线程Runnable,状态:" + Thread.currentThread().getState());
});
// 主线程打印thread1线程状态
System.out.println("thread1线程New,状态:" + thread1.getState());
// 启动thread1线程
thread1.start();
// 主线程睡眠0.5秒,等待thread1线程启动,执行LockSupport.parkUntil()
Thread.sleep(500);
// 主线程打印thread1线程状态
System.out.println("thread1线程TIMED_WAITING,状态:" + thread1.getState());
// 主线程等待thread1执行完毕
thread1.join();
// 主线程打印thread1线程状态
System.out.println("thread1线程TERMINATED,状态:" + thread1.getState());
}
}
更多推荐



所有评论(0)