等待唤醒案例分析(线程之间的通信)

📅 2026/6/30 5:58:23
等待唤醒案例分析(线程之间的通信)
方法说明void wait()线程等待,等待的过程中线程会释放锁,需要被其他线程调用notify方法将其唤醒,重新抢锁执行但是并不会重新执行全部代码void notify()线程唤醒,一次唤醒一个等待线程;如果有多条线程等待,则随机唤醒一条等待线程void notifyAll()唤醒所有等待线程wait和notify方法需要锁对象调用,所以需要用到同步代码块中,而且必须是同一个锁对象2.等待唤醒案例实现/* count和flag可以定义成包装类 但是要记得给count和flag手动赋值 不然对于本案例来说,容易出现空指针异常 */ public class BaoZiPu { //代表包子的count private int count; //代表是否有包子的flag private boolean flag; public BaoZiPu() { } public BaoZiPu(int count, boolean flag) { this.count count; this.flag flag; } /* getCount 改造成消费包子方法 直接输出count */ public void getCount() { System.out.println(消费了..............第count个包子); } /* setCount 改造成生产包子 count */ public void setCount() { count; System.out.println(生产了...第count个包子); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } }public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为true,如果是true,证明有包子,生产线程等待 if (baoZiPu.isFlag()true){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为false,证明没有包子,开始生产 baoZiPu.setCount(); //3.改变flag状态,为true,证明生产完了,有包子了 baoZiPu.setFlag(true); //4.唤醒消费线程 baoZiPu.notify(); } } } }public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (baoZiPu){ //1.判断flag是否为false,如果是false,证明没有包子,消费线程等待 if (baoZiPu.isFlag()false){ try { baoZiPu.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为true,证明有包子,开始消费 baoZiPu.getCount(); //3.改变flag状态,为false,证明消费完了,没 有包子了 baoZiPu.setFlag(false); //4.唤醒生产线程 baoZiPu.notify(); } } } }public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu new BaoZiPu(); Product product new Product(baoZiPu); Consumer consumer new Consumer(baoZiPu); Thread t1 new Thread(product); Thread t2 new Thread(consumer); t1.start(); t2.start(); } }总结在该实例中我们要考虑的是同步和互斥的问题我们要实现生产一个消费一个并且仅仅只有一个生产者和消费者这就要考虑到两个线程访问同一个资源的问题我们利用同步代码进行上锁处理还需要考虑生产和消费者的顺序问题我们使用wait和notify两个api进行实现。​ 我们利用同步代码在消费者和生产者中进行重写了run方法我们利用对象实例进行作为mutex互斥锁利用一个变量来判断是否已经生产还是消费若判断成功则放在该实例对象的等待队列中否则进行操作然后随机唤醒等待队列的进程。3.用同步方法改造等待唤醒案例/* count和flag可以定义成包装类 但是要记得给count和flag手动赋值 不然对于本案例来说,容易出现空指针异常 */ public class BaoZiPu { //代表包子的count private int count; //代表是否有包子的flag private boolean flag; public BaoZiPu() { } public BaoZiPu(int count, boolean flag) { this.count count; this.flag flag; } /* getCount 改造成消费包子方法 直接输出count */ public synchronized void getCount() { //1.判断flag是否为false,如果是false,证明没有包子,消费线程等待 if (this.flag false) { try { this.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为true,证明有包子,开始消费 System.out.println(消费了..............第 count 个包子); //3.改变flag状态,为false,证明消费完了,没 有包子了 this.flag false; //4.唤醒生产线程 this.notify(); } /* setCount 改造成生产包子 count */ public synchronized void setCount() { //1.判断flag是否为true,如果是true,证明有包子,生产线程等待 if (this.flag true) { try { this.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } //2.如果flag为false,证明没有包子,开始生产 count; System.out.println(生产了...第 count 个包子); //3.改变flag状态,为true,证明生产完了,有包子了 this.flag true; //4.唤醒消费线程 this.notify(); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag flag; } }public class Product implements Runnable{ private BaoZiPu baoZiPu; public Product(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.setCount(); } } }public class Consumer implements Runnable{ private BaoZiPu baoZiPu; public Consumer(BaoZiPu baoZiPu) { this.baoZiPu baoZiPu; } Override public void run() { while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { throw new RuntimeException(e); } baoZiPu.getCount(); } } }public class Test01 { public static void main(String[] args) { BaoZiPu baoZiPu new BaoZiPu(); Product product new Product(baoZiPu); Consumer consumer new Consumer(baoZiPu); Thread t1 new Thread(product); Thread t2 new Thread(consumer); t1.start(); t2.start(); } }