wait、notify、notifyAll
| 1、在多线程环境下,有时候一个线程的执行,依赖于另外一个线程的某种状态的改变,这个时候,我们就可以使用wait与notify或者notifyAll |
| 2、wait跟sleep的区别:wait会释放持有的锁,而sleep不会,sleep只是让线程在指定的时间内,不去抢占cpu的资源 |
| 3、注意点:wait notify必须放在同步代码块中, 且必须拥有当前对象的锁,即不能取得A对象的锁,而调用B对象的wait 哪个对象wait,就得调哪个对象的notify |
| 4、notify跟notifyAll的区别:nofity随机唤醒一个等待的线程 notifyAll唤醒所有在该对象上等待的线程 |
| public class Demo { |
| |
| private static volatile boolean flag = false; |
| |
| public static void main(String[] args) throws InterruptedException { |
| |
| new Thread(()->{ |
| while (!flag) { |
| try { |
| Thread.sleep(1000L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| System.out.println("flag is false"); |
| } |
| System.out.println("flag is true"); |
| }).start(); |
| |
| |
| Thread.sleep(1000L); |
| |
| |
| new Thread(()->{ |
| flag = true; |
| }).start(); |
| } |
| |
| } |
| |
| # 控制台结果: |
| flag is false |
| flag is true |
| public class Demo1 { |
| |
| private static volatile boolean flag = false; |
| |
| public static void main(String[] args) throws InterruptedException { |
| |
| Object obj = new Object(); |
| |
| new Thread(()->{ |
| while (!flag) { |
| synchronized (obj) { |
| try { |
| System.out.println("flag is false"); |
| obj.wait(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| System.out.println("flag is true"); |
| }).start(); |
| |
| new Thread(()->{ |
| while (!flag) { |
| synchronized (obj) { |
| try { |
| System.out.println("flag is false"); |
| obj.wait(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| System.out.println("flag is true"); |
| }).start(); |
| |
| |
| Thread.sleep(1000L); |
| |
| new Thread(()->{ |
| flag = true; |
| synchronized (obj) { |
| obj.notifyAll(); |
| } |
| }).start(); |
| } |
| |
| } |
| |
| # 控制台 |
| flag is false |
| flag is false |
| flag is true |
| flag is true |
等待通知经典模型之生产者消费者

| # 中间商 |
| public class Medium { |
| |
| private int num = 0; |
| |
| private static final int TOTAL = 20; |
| |
| |
| |
| |
| public synchronized void put() { |
| |
| if (num < TOTAL) { |
| |
| System.out.println("新增库存-------->当前库存" + ++num); |
| try { |
| Thread.sleep(500L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| notifyAll(); |
| } else { |
| |
| try { |
| System.out.println("新增库存---------> 库存已满"+num); |
| wait(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| |
| |
| |
| public synchronized void take() { |
| |
| if (num > 0) { |
| |
| System.out.println("消费库存-----------> 当前库存容量" + --num); |
| try { |
| Thread.sleep(1000L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| notifyAll(); |
| } else { |
| |
| System.out.println("消费库存-----------> 库存不足"+num); |
| try { |
| wait(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| } |
| |
| # 生产者 |
| public class Producer implements Runnable { |
| |
| private Medium medium; |
| |
| public Producer(Medium medium) { |
| this.medium = medium; |
| } |
| |
| @Override |
| public void run() { |
| while (true) { |
| medium.put(); |
| } |
| } |
| |
| } |
| |
| # 消费者 |
| public class Consumer implements Runnable{ |
| |
| private Medium medium; |
| |
| public Consumer(Medium medium) { |
| this.medium = medium; |
| } |
| |
| @Override |
| public void run() { |
| while (true) { |
| medium.take(); |
| } |
| } |
| |
| } |
| |
| # 测试类 |
| public class Main { |
| |
| public static void main(String[] args) { |
| Medium medium = new Medium(); |
| |
| new Thread(new Consumer(medium)).start(); |
| new Thread(new Consumer(medium)).start(); |
| new Thread(new Consumer(medium)).start(); |
| |
| new Thread(new Producer(medium)).start(); |
| new Thread(new Producer(medium)).start(); |
| new Thread(new Producer(medium)).start(); |
| new Thread(new Producer(medium)).start(); |
| new Thread(new Producer(medium)).start(); |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~