线程等待唤醒几种方法

线程等待和唤醒有三种实现方法,分别是Object类中的wait、notify;Condition类中的await、signal;LockSupport类中的park、unpark方法。

1、Object类中的wait、notify必须配合Synchronized关键字一起使用,否则会抛出IllegalMonitorStateException异常,并且notify唤醒需要在wait之后,否则无法唤醒。

java 复制代码
	public static void main(String[] args) {

		Object o = new Object();
		new Thread(()->{
			synchronized (o) {
				try {
					o.wait();
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
				System.out.println("被唤醒");
			}
		}).start();

		System.out.println("准备唤醒");
		synchronized (o) {
			o.notify();
		}
   }

2、Condition类中的await、signal必须配合Lock.lock、unlock一起使用,否则会抛出IllegalMonitorStateException异常,并且signal唤醒需要在await之后使用,否则无法唤醒。

java 复制代码
	public static void main(String[] args) {

		Lock reentrantLock = new ReentrantLock();
		Condition condition = reentrantLock.newCondition();

		new Thread(()->{
			reentrantLock.lock();
			try {
				condition.await();
				System.out.println("被唤醒");
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			} finally {
				reentrantLock.unlock();
			}
		}).start();

		System.out.println("准备唤醒");

		reentrantLock.lock();
		try {
			condition.signal();
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} finally {
			reentrantLock.unlock();
		}
   }

3、LockSupport类中的park、unpark属于静态方法,unpark会生成许可证,park会消费许可证。先调用park如果未生成许可证,那么会阻塞等待unpark生成许可证,并不会抛出异常。他们只和线程关联,且线程最多只能有一个许可证,这意味着每次生成凭证之后,需要等消费完才能继续生成凭证。

java 复制代码
	public static void main(String[] args) {
		Thread thread = new Thread(() -> {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
			LockSupport.park();
			System.out.println("被唤醒");
		});
		thread.start();


		System.out.println("准备唤醒");
        //断点可以看到unpark先执行,之后执行park
		LockSupport.unpark(thread);
        //thread.start()在unpark之后无效,线程必须启动才能unpark成功
	}
相关推荐
杨凯凡14 分钟前
Spring Framework 7 API 版本管理实战:请求头路由、兼容迁移与废弃策略
java·rest api·springframework·spring boot 4·api版本管理
T_Wizard40 分钟前
同一个问题写了 4 遍:官方 SDK / HTTP / Spring AI / LangChain4j,到底该选哪个
java·ai编程
hai_android42 分钟前
AudioTrack 深度解析:从原理到实战
android·java·kotlin
斯维赤1 小时前
限流、熔断、降级,你真的分得清吗?
java·后端·架构
Evand J2 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
BaiPeter3 小时前
ZPL文件预览
开发语言·c++
aiks_yuan4 小时前
Java CPU 100% 怎么排查:JDK 11 起 jstack 自带线程 CPU 时间,不用再 top -H 换算十六进制(JDK 8、11、17 实测)
java
Flynn Liang5 小时前
AiServices 源码级拆解:一个接口如何变成 RAG Agent
java·langchain·源码分析·rag·langchain4j·aiservices
Flynn Liang5 小时前
LangChain4j 1.23 架构全景:Java 大模型应用的 6 层抽象
java·langchain·大模型·rag·ai agent·langchain4j
聪明的笨猪猪6 小时前
实际工程问题:AI生成Redis分布式锁的原子性缺陷导致库存超卖
java·经验分享·面试·ai编程