七、等待唤醒的三种方式
一、Object的wait、notify
注:
1、wait、notify必须绑定synchronized使用。
2、wait、notify有先后顺序,必须先等待后唤醒。
3、wait后,会释放锁。
public class TestDemo01 { static Object obj = new Object(); public static void main(String[] args) { syncWaitNotify(); } private static void syncWaitNotify() { new Thread(() -> { synchronized (obj) { System.out.println(Thread.currentThread().getName() + " come in"); try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 被唤醒"); } }, "A").start(); new Thread(() -> { synchronized (obj) { obj.notify(); System.out.println(Thread.currentThread().getName() + " 通知"); } }, "B").start(); } }
二、Condition的await、signal
注:
1、await、signal必须绑定lock使用。
2、await、signal有先后顺序,必须先等待后唤醒。
public class TestDemo01 {static Lock lock = new ReentrantLock(); static Condition condition = lock.newCondition(); public static void main(String[] args) { lockAwaitSignal(); } private static void lockAwaitSignal() { new Thread(() -> { lock.lock(); try { System.out.println(Thread.currentThread().getName() + " come in"); condition.await(); System.out.println(Thread.currentThread().getName() + " 被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }, "A").start(); new Thread(() -> { lock.lock(); try { condition.signal(); System.out.println(Thread.currentThread().getName() + " 通知"); } finally { lock.unlock(); } }, "B").start(); } }
三、LockSupport的park、unpark
LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞喝唤醒线程的功能,每个线程都有一个许可(permit),permit只有1和0两个值,默认0。
注:
1、park、unpark无需依赖锁。
2、park、unpark没有先后顺序,可以先通知,再唤醒。先upark()后,park()不会执行。
3、unpark()不可累计,无法唤醒线程中的多个park()。
4、LockSupport是调用Unsafe中的native代码。
public class LockSupportDemo {public static void main(String[] args) { lockSupport(); } private static void lockSupport() { Thread a = new Thread(() -> { System.out.println(Thread.currentThread().getName() + " come in"); LockSupport.park(); System.out.println(Thread.currentThread().getName() + " 被唤醒"); }, "a"); a.start(); // 暂停3s线程 try { TimeUnit.SECONDS.sleep(3L); } catch (InterruptedException e) { e.printStackTrace(); } Thread b = new Thread(() -> { LockSupport.unpark(a); System.out.println(Thread.currentThread().getName() + " 通知"); }, "b"); b.start(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)