------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

  多线程可以让我们同时共享一个资源,但如果在共享这个资源时需要彼此之间的联系怎么做呢?

经典实例:生产者与消费者。

问题描述,生产者每生产一个消费者就要取走一个,同时进行。

首先java为我们提供了一套等待唤醒机制,让线程与线程之间产生了联系。线程是分五个状态的:创建;运行;阻塞;冻结;消亡。java提供了几个针对状态的方法

wait()方法让线程进入冻结状态,让出cpu,让出锁;

notify()方法唤醒进入冻结状态的线程,notifyAll()是唤醒所有的线程。

针对问题,我们可以对生产者设定一个开关,如果资源为0就允许其生产并在生产完之后将开关关上,不会在有生产者生产并唤醒其他线程也就是消费者线程,当然在这之上同样要用到同步,为了保证第一个生产者进去之时,其他生产者会被拒之门外,对于消费者同理。

public static void main(String[] args) {// tongbu i=new tongbu();//创建抽取出来的同步方法对象hjw j=new hjw(i);//创建实现Runnable接口的对象bb k=new bb(i);Thread xc1 =new Thread(j);//创建线程Thread xc2 =new Thread(k);xc1.setName("生产者");xc2.setName("消费者");xc1.start();xc2.start();}}
class tongbu{//将两个同步方法抽取出来private String name;private int count=1;boolean flag=false;//定义一个bool类型来作用等待唤醒机制public synchronized void set(String name){//生产者的同步函数if(flag){//已存在就睡眠try{wait();}catch(Exception e){}}//否则 运作代码this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+this.name);flag=true;//改变bool值this.notify();//唤醒线程}public synchronized void get(){if(!flag){//进入休眠try{wait();}catch(Exception e){}}//被生产者唤醒System.out.println(Thread.currentThread().getName()+"---"+this.name);flag=false;this.notify();//唤醒线程}
}
class hjw implements Runnable{private tongbu x ;hjw(tongbu x){//传回tongbu对象this.x=x;}public void run(){//重写run方法while(true){x.set("饼干");}}
}
class bb implements Runnable{private tongbu x ;bb(tongbu x){//传回tongbu对象this.x=x;}public void run(){//重写run方法while(true){x.get();}}
}

  这只是对于生产者和消费者只有一个线程,如果这边都有多个线程呢?绝不是多创建几个线程那么简单,因为要notify方法是唤醒最先休眠的那个线程,也就是说转到后面会出,生产一个,消费两次,生产多个只消费其中一个。

那么如何避免呢?采用while循环替代if循环,每当线程解冻之后,重新开始循环而非接着向下执行,这样就避免了多次执行,但问题是依据notify()的特性还是会让所有线程都陷入等待,我需要唤醒对方线程,所有这个时候就要用到notifyAll()了,唤醒所有线程。

public static void main(String[] args) {// tongbu i=new tongbu();//创建抽取出来的同步方法对象hjw j=new hjw(i);//创建实现Runnable接口的对象bb k=new bb(i);Thread xc1 =new Thread(j);//创建线程Thread xc2 =new Thread(k);xc1.setName("生产者");xc2.setName("消费者");xc1.start();xc2.start();}}
class tongbu{//将两个同步方法抽取出来private String name;private int count=1;boolean flag=false;//定义一个bool类型来作用等待唤醒机制public synchronized void set(String name){//生产者的同步函数while(flag){//已存在就睡眠try{wait();}catch(Exception e){}}//否则 运作代码this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+this.name);flag=true;//改变bool值this.notifyAll();//唤醒线程}public synchronized void get(){while(!flag){//进入休眠try{wait();}catch(Exception e){}}//被生产者唤醒System.out.println(Thread.currentThread().getName()+"---"+this.name);flag=false;this.notifyAll();//唤醒线程}
}
class hjw implements Runnable{private tongbu x ;hjw(tongbu x){//传回tongbu对象this.x=x;}public void run(){//重写run方法while(true){x.set("饼干");}}
}
class bb implements Runnable{private tongbu x ;bb(tongbu x){//传回tongbu对象this.x=x;}public void run(){//重写run方法while(true){x.get();}}
}

  事实上,java5.0版本提供更完善的解决方案,针对如何唤醒指定线程。在java.lang.util.concurrent.locks中,提供了方法将锁显示化用以取代同步synchronized,lock()开锁,unlock()关锁,关锁这一特点犹如关闭资源就是无论怎样都要执行,因为前面有异常需要处理,所以关锁这一操作放在了finally{}中;而对于Object中wait()方法和notify(),notifyAll()方法分别用condition的await(),signal()和signalAll()取代,在lock中有一个new condition的方法,所以可以通过创建多个condition类,实现对指定线程的操作。

转载于:https://www.cnblogs.com/huangjiawei/p/4706314.html

黑马程序员————java线程之间的通信相关推荐

  1. 黑马程序员Java零基础视频教程_下部(P135-P200)

    黑马程序员Java零基础视频教程_下部(P135-P200) 1 多线程 1.1 什么是多线程? 1.2 多线程的并发与并行 1.3 多线程的实现方式 1.3.1 继承Thread类的方式进行实现 1 ...

  2. 2023年黑马程序员Java学习路线图

    2023年Java学科免费学习资源放送40+套课程,超过600小时的内容! 在过去的一年里,为了帮助更多人线上充电,学会更多技能,黑马程序员举办了 150+ 场免费直播公开课,新增精品视频教程 80+ ...

  3. 黑马程序员Java教程学习笔记(五)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...

  4. 黑马程序员 JAVA WEB 第三节 MYSQL 约束

    这是阿锃总结的第三节黑马程序员JAVA WEB视频的MYSQL约束部分的笔记.希望可以帮助跟我一样正在学习Java web的同学们.我们一起进步.   b_d 若果有同学也想学习黑马程序员Java w ...

  5. 黑马程序员Java零基础视频教程_下部(P52-P134)

    黑马程序员Java零基础视频教程_下部(P52-P134) 1. 异常 1.1 异常体系介绍 1.2 编译时异常和运行时异常 1.3 异常在代码中的两个作用 1.4 JVM虚拟机默认处理异常的方式 1 ...

  6. 黑马程序员Java零基础视频教程_上部(P1-P80)

    黑马程序员Java零基础视频教程_上部(P1-P80) 1. Java入门 1.1 Java学习介绍 1.2 Java人机交互 1.2.1 常用CMD命令 2. Java基础学习 2.1 Java入门 ...

  7. 黑马程序员——Java字符流、字节流IO流

    黑马程序员--Java字符流.字节流Io流 ---------------------- <a href="http://www.itheima.com"target=&qu ...

  8. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  9. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

最新文章

  1. mysql mysqlhotcopy_MySQL备份之mysqlhotcopy与注意事项
  2. LVS入门篇(二)之LVS基础
  3. 【RTMP协议分析与抓包实测】
  4. 【CodeForces - 1152C 】Neko does Maths(数学数论,lcm,gcd性质)
  5. flask框架(三):flask配置文件
  6. 项目结构_组织结构对项目影响系列课程---项目式组织结构
  7. 百度云虚拟服务器搭建,百度云虚拟主机实力呈现 网站搭建最优选择
  8. 2020-03-25 赵子清汇编语言教程
  9. 机器学习基础(二十五)—— Feature Selection
  10. Android学习笔记(17):文本框TextView类
  11. ROLLUP函数问题
  12. 《Intriguing Properties of Contrastive Losses》阅读笔记
  13. 毕业论文图片、公式自动编号和交叉索引教程——真的超好用
  14. echarts 省级地图下钻到市demo
  15. 点击遮罩层的背景关闭遮罩层
  16. 花火4G聚合路由器无线网络支持5G户外直播应急通讯工作
  17. 张首晟:区块链技术是互联网世界新的分合转折点
  18. ps3模拟器android,ps3模拟器手机版
  19. 安卓无障碍API封装库: Android-Accessibility-Api
  20. 关于module 'XXX' has no attribute 'XXX'**的二三事

热门文章

  1. 浅谈内联元素inline
  2. JavaScript小技巧总结
  3. Oracle行转列、列转行的Sql语句总结
  4. 详细介绍android rom移植知识普及
  5. 样式定义Android界面样式
  6. c语言程序设计abcd拍大小,《C语言程序设计》选择、填空。热门考题
  7. 钣金cad插件_ug,CAD,SolidWorks,钣金??????非标等设计
  8. java对excel加密_Java 加密、解密Excel文档
  9. 后端自我介绍_新人入职自我介绍
  10. 文本文件 java_Java入门:读写文本文件