java 挂起线程
目录
JDK中提供挂起线程的方式
suspend与resume
suspend作用
挂起线程, 不会释放锁,并且线程的状态是 RUNNABLE
resume作用
唤醒线程
注意事项
- JDK已废弃该方法
- suspend会挂起线程但是不会释放锁并且状态还是处于RUNNABLE状态
- resume必须在suspend之后调用,否则线程会一直处于挂起状态
示例代码
package com.nanxhs.concurrent.thread.pause;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* 使用suspend与resume 挂起/唤醒线程例子
*
* @author: haibin.tang
* @date: 2021/1/28
*/
public class SuspendSample {
private static final Queue<Integer> SEQUENCE_QUEUE = new LinkedBlockingDeque<>();
private Thread productionThread;
private Thread consumerThread;
private void productionThread() {
productionThread = new Thread(() -> {
while (true) {
int code = (int)(Math.random() * 10000);
SEQUENCE_QUEUE.add(code);
System.out.println(Thread.currentThread().getName() + "-生产序号 -->>> " + code);
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
if (SEQUENCE_QUEUE.size() > 2) {
consumerThread.resume();
productionThread.suspend();
}
}
});
}
private void consumerThread() {
consumerThread = new Thread(() -> {
while (true) {
if (SEQUENCE_QUEUE.size() < 1) {
productionThread.resume();
consumerThread.suspend();
}
System.out.println(Thread.currentThread().getName() + "-消费序号 -->>> " + SEQUENCE_QUEUE.poll());
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
}
});
}
public static void main(String[] args) {
SuspendSample suspendSample = new SuspendSample();
suspendSample.productionThread();
suspendSample.consumerThread();
suspendSample.productionThread.start();
suspendSample.consumerThread.start();
}
}
运行结果
Thread-0-生产序号 -->>> 597
Thread-0-生产序号 -->>> 6090
Thread-0-生产序号 -->>> 5156
Thread-1-消费序号 -->>> 597
Thread-1-消费序号 -->>> 6090
Thread-1-消费序号 -->>> 5156
Thread-0-生产序号 -->>> 205
Thread-0-生产序号 -->>> 5190
Thread-0-生产序号 -->>> 8090
Thread-1-消费序号 -->>> 205
Thread-1-消费序号 -->>> 5190
Thread-1-消费序号 -->>> 8090
结论
当调用suspend()方法后,线程会挂起,但是状态还是处于RUNNABLE; 如下图:
使用LockSupport工具方法
API定义
特点
- 调用 public static void parkNanos(long nanos) 方法后线程状态会变为 TIMED_WAITING
- 调用 public static void park() 方法后线程状态会变为 WAITING
- 相比于suspend/resume 线程状态不会让人迷惑
Thread#join()
示例代码
package com.nanxhs.concurrent.thread.pause;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* 使用join挂起线程示例
*
* @author: haibin.tang
* @date: 2021/1/29
*/
public class JoinSample {
private static final Queue<Integer> SEQUENCE_QUEUE = new LinkedBlockingDeque<>();
private Thread printCodeThread;
private void initSequence() {
for (int index = 10000; index < 10010; ++index) {
SEQUENCE_QUEUE.add(index);
}
}
private void printCodeThread() {
printCodeThread = new Thread(() -> {
while (SEQUENCE_QUEUE.size() > 1) {
System.out.println("消费code -->>> " + SEQUENCE_QUEUE.poll());
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
}
});
}
public static void main(String[] args) throws InterruptedException {
JoinSample joinSample = new JoinSample();
joinSample.initSequence();
joinSample.printCodeThread();
joinSample.printCodeThread.start();
joinSample.printCodeThread.join();
System.out.println("等待打印序号线程结束");
}
}
运行结果
消费code -->>> 10000
消费code -->>> 10001
消费code -->>> 10002
消费code -->>> 10003
消费code -->>> 10004
消费code -->>> 10005
消费code -->>> 10006
消费code -->>> 10007
消费code -->>> 10008
等待打印序号线程结束
结论
- 调用join后,当前线程会处于WATTING状态, 直到 等待的线程运行完毕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南