例题:使用两个线程打印 1-100。线程1, 线程2 交替打印。

解决:涉及wait()notify()/notifyAll()

class Communicate implements Runnable {private int number = 1;@Overridepublic void run() {while (true) {synchronized (this) {this.notify();if (number <= 100){System.out.println(Thread.currentThread().getName() + "打印出" + number);number++;try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}else break;}}}
}public class CommunicateTest {public static void main(String[] args) {Communicate communicate = new Communicate();Thread thread1 = new Thread(communicate);Thread thread2 = new Thread(communicate);thread1.setName("线程一");thread2.setName("线程二");thread1.start();thread2.start();}
}

wait():令当前线程挂起,放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当前线程排队等候其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有权后才能继续执行。

notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待。

notifyAll():唤醒正在排队等待资源的所有线程结束等待。

这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报
java.lang.IllegalMonitorStateException异常。

这三个方法的调用者都必须是同步监视器,即如同步监视器.wait()。例如以上代码中的同步监视器是本对象this。

这三个方法是定义在Object类中的,而非Thread。


sleep() 和wait()的异同:

1.相同点:一 旦执行方法,都可以使得当前的线程进入阻塞状态。
2.不同点:①两个方法声明的位置不同: Thread类中声明sleep() ,Object类中声明wait()。②调用的要求不同: sleep() 可以在任何需要的场景下调用,wait( )必须使用在同步代码块或同步方法中。③关于是否释放同步监视器: 如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。


经典例题:生产者/消费者问题

生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。

①店员(产品):

//店员(产品)
class Clerk {private int productNum = 0;public synchronized void addProduct() {if (productNum < 20){productNum++;System.out.println(Thread.currentThread().getName() + ":生产的第" + productNum + "个产品");notifyAll();}else {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void getProduct() {if (productNum > 0){productNum--;System.out.println(Thread.currentThread().getName() + ":消费的第" + productNum + "个产品");notifyAll();}else {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}
}

②生产者:

//生产者
class Productor implements Runnable {private Clerk clerk;public Productor(Clerk clerk) {this.clerk = clerk;}@Overridepublic void run() {System.out.println("生产者开始生产产品");while (true) {try {Thread.sleep((int) Math.random() * 1000);} catch (InterruptedException e) {e.printStackTrace();}clerk.addProduct();}}
}

③消费者:

//消费者
class Consumer implements Runnable {private Clerk clerk;public Consumer(Clerk clerk) {this.clerk = clerk;}public void run() {System.out.println("消费者开始取走产品");while (true) {try {Thread.sleep((int) Math.random() * 1000);} catch (InterruptedException e) {e.printStackTrace();}clerk.getProduct();}}
}

④主进程main

public class ProductTest {public static void main(String[] args) {Clerk clerk = new Clerk();Productor productor = new Productor(clerk);Consumer consumer = new Consumer(clerk);Thread thread1 = new Thread(productor);Thread thread2 = new Thread(consumer);thread1.setName("生产者");thread2.setName("消费者");thread1.start();thread2.start();}
}

Java多线程(5)--线程通信wait和notify相关推荐

  1. Java多线程之线程通信之生产者消费者阻塞队列版

    Java多线程之线程通信之生产者消费者传统版和阻塞队列版 目录 线程通信之生产者消费者传统版 线程通信之生产者消费者阻塞队列版 1. 线程通信之生产者消费者传统版 题目: 一个初始值为零的变量,两个线 ...

  2. java 多线程 8 : 线程通信

    wait(): 使当前线程等待,直到其他线程调用该同步监视器notify()方法 , 或者notifyAll()方法来唤醒该线程. wai()方法有三种形式 , 无参的一直等 :带毫秒的 , 和带微秒 ...

  3. java 管程通信_Java多线程07_线程通信之管程法与信号灯法

    Java多线程07_线程通信之管程法与信号灯法 线程通信 的应用场景是 消费者/生产者问题: 解决线程通信的方法: wait()表示线程一直等待,直到接到通知(会释放锁) wait(long time ...

  4. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  5. 多线程笔记补充之线程通信wait和notify方法以及Lock和Condition接口的使用

    线程通信-wait和notify方法介绍: java.lang.Object类提供类两类用于操作线程通信的方法. wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中,等待其他的 ...

  6. Java多线程间的通信

    Java多线程间的通信 Java还提供了一种线程间通信的机制,这种通信通什么实现? wait,notify等机制    或使用pipeInputStream和pipeOutputStream 1. 线 ...

  7. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  8. java多线程方式轮询,深入理解JAVA多线程之线程间的通信方式

    一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过sy ...

  9. Java多线程:线程间通信方式

    文章目录 Java线程通信 wait().notify().notifyAll() API说明 实现原理 代码实现 await().signal().signalAll() API说明 实现原理 代码 ...

  10. Java多线程与线程并发库高级应用笔记

    以下内容是学习张老师Java多线程与线程并发库高级应用时所做的笔记,很有用 网络编辑器直接复制Word文档排版有点乱,提供原始文件下载 先看源文件概貌 张孝祥_Java多线程与并发库高级应用 [视频介 ...

最新文章

  1. python【蓝桥杯vip练习题库】BASIC-25 回形取数
  2. Qt中如何获取系统图标
  3. keil obj 文件 结构_【Python】数据分析前的入门教程 Python For Everybody P2:数据结构...
  4. sorl java 建索引_solr 的客户端调用solrj 建索引+分页查询
  5. 利用Eclipse的JPA自动生成注解实体
  6. FastDFS 安装
  7. Android之解决主页面Activity监听fragment退出问题(由NavHostFragment和RxFragment一起管理fragment)
  8. Eigen 简明教程之如何从Python转到Eigen
  9. Java并发(二)——ThreadLocal
  10. 人脑、思维与认知的研究
  11. C语言:采用交互式方式打开指定的文件,若文件打开成功,则显示该文件的大小,并显示文件内容,若文件打开失败,则提示出错信息
  12. mongodb C++ Driver安装
  13. java常用类--------枚举的基本使用
  14. 新手干货:Vue - 常用指令
  15. c++中#pragma用法详解
  16. JavaScript基础知识总结(6张思维导图)
  17. 女人,百花千红你最美
  18. Kubuntu中搜狗拼音输入法候选框乱码问题解决
  19. 青龙2.10.13 稳定版+xdd-plus+阿东教程保姆教程(2022年7月11日更新)
  20. mac 端口被占用 解决方案

热门文章

  1. Java 7:HashMap与ConcurrentHashMap
  2. kali用x-shell连接_良心国产工具,比Xshell好用还免费!
  3. 当集合a为空集时a的取值范围_高中数学必修一第一章集合分节练习和章末测试题含答案[1] 2...
  4. Windows下查看wifi密码的命令
  5. 判断选择语句switch...case
  6. 微软家庭服务器,微软公布Windows Server 2012版本方案,不再提供家庭服务器版
  7. @insert 对象_python中列表插入append(), extend(), insert()
  8. 【H.264/AVC视频编解码技术】第四章【SPS序列参数集】
  9. java规则表达式_Java基础--正则表达式的规则
  10. C语言中quot;##quot;的独特用法