package example; import java.util.LinkedList;
import java.util.concurrent.TimeUnit; public class MyContainer3<T> { final private LinkedList<T> lists = new LinkedList<T>();
final private int MAX = 10; //最多10个元素
private int count = 0; public synchronized void put(T t){
while(lists.size()==MAX){
try {
this.wait(); //wait 99%和while结合使用,而不是和if结合使用
//容器满了,在这里wait,被叫醒时,直接是往下执行的,还没运行到往里扔的适合,另外一个线程往里扔了,导致出错。
//如果用while时,他会继续再检查一遍,醒了的时候,再检查一遍。 notifyAll可以叫醒多个线程。
} catch (InterruptedException e) {
e.printStackTrace();
}
} lists.add(t);
count++;
this.notifyAll();
} public synchronized T get(){
while(lists.size()==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t = lists.removeFirst();
count--;
/**注意唤醒*/
this.notifyAll();
return t;
} public static void main(String[] args) { MyContainer3<String> c = new MyContainer3<>(); //启动消费者线程
for(int i=0; i<10; i++) {
new Thread(()->{
for(int j=0; j<5; j++) System.out.println(Thread.currentThread().getName() +"--"+c.get());
}, "c" + i).start();
} try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
} //启动生产者线程
for(int i=0; i<2; i++) {
new Thread(()->{
for(int j=0; j<25; j++) c.put(Thread.currentThread().getName() + " " + j);
}, "p" + i).start();
}
} }

面试点:关于为什么用while 而不用if

wait 99%和while结合使用,而不是和if结合使用

容器满了,然后空了一个,此时有两个线程都醒了,他们都要争取到那一把锁,结果t2把那把锁抢到了,然后它向容器里放了容器,此时当t1再次被获得锁时,它就不会检查容器的容量,而继续向下执行,导致出错,如果用while的话,它会回到上面再检查一次,然后睡眠。


面试点:为什么用notifyAll 而不用notify?

因为如果生产者生产满了容器后,它notify的另外一个线程也是生产者,结果他去运行的时候。也直接wait了,这个时候,程序就死了,因为所有的线程都睡了。

effective java 永远不要去使用notify而使用notifyAll

Java并发案例02---生产者消费者问题的更多相关文章

  1. 使用Java的BlockingQueue实现生产者-消费者

    http://tonl.iteye.com/blog/1936391 使用Java的BlockingQueue实现生产者-消费者 博客分类: Java JavaBlockingQueue阻塞队列  B ...

  2. Java并发案例03---生产者消费者问题02

    生产者消费者第二种情形 package com.maple.msb.one; public class ProducerConsumer { public static void main(Strin ...

  3. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  4. JAVA并发实现五(生产者和消费者模式wait和notify方式实现)

    package com.subject01; import java.util.PriorityQueue; /** * 通过wait和notify 实现 * 生产者-消费者模型:当队列满时,生产者需 ...

  5. JAVA多线程经典问题 -- 生产者 消费者

    工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...

  6. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  7. Java多线程14:生产者/消费者模型

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  8. Java 管程解决生产者消费者问题

    同样是实验存档.//.. 依然以生产者消费者问题作为背景. 管程(=“资源管理程序”)将资源和对资源的操作封装起来,资源使用者通过接口操作资源就 ok,不用去考虑进程同步的问题. 管程: packag ...

  9. day34 并发编程之生产者消费者模型 队列

    1.守护进程(了解) """ 守护进程 表示 一个进程b 守护另一个进程a 当被守护的进程a结束后 那么b也跟着结束了 就像 皇帝驾崩 妃子殉葬 应用场景 之所以开启子进 ...

  10. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

随机推荐

  1. WCF-终结点之消息路由示例

    一. 在前一章中主要介绍了服务端的监听地址与逻辑地址.本节模拟消息转发机制来实际体验一把终结点的监听地址是如何使用的. 先下载一个叫做TcpTrace的小软件(108k),它能够截取端口消息,并转发消 ...

  2. zsh: command not found: gulp

    明明安装了gulp,但是为什么执行gulp命令却在控制台输出 zsh: command not found: gulp 可能因为gulp没有被全局安装 在控制台输入 which gulp 如果输出 g ...

  3. ASP.NET之HTML

    1.什么是html 用来描述网页的2.开发工具我们肯定是用vs啦3.img src 图片地址 <img src="img/aa.bmp" />; 4.超链接a标签 hr ...

  4. 撩课-Web大前端每天5道面试题-Day11

    1. 如何手写一个JQ插件? 方式一: $.extend(src) 该方法就是将src合并到JQ的全局对象中去: $.extend({ log: ()=>{alert('撩课itLike');} ...

  5. 深入辨析jvm内存区域

    Java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域: 程序计数器.虚拟机栈.本地方法栈.Java堆.方法区(运行时常量池).直接内存 程序计数器 当 ...

  6. js 数组常用的一些方法

    数组可以说是js经常会遇到的数据结构,以下我们对数组进行详细的学习! 一.数组的创建 var mycars = new Array(): || new Array(3);  || new Array( ...

  7. java poi处理新版xlsx后缀的excel

    jar包下载地址http://poi.apache.org/download.html#POI-3.17,我把下载文件中的所有jar包都导入项目中才能跑 参考以下博客 https://www.cnbl ...

  8. CentOS6下docker的安装和使用

    CentOS6下docker的安装和使用 Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS.Go语言.cgroup ...

  9. 用fritzing绘制arduino硬件连线图

    在http://fritzing.org/home/ 点击下载最新版本. 解压之后直接可以使用. 打开Fritzing.exe 在点击面包板,在搜索界面输入想要找到的原件拖拽即可放在面包板所在的图上. ...

  10. BZOJ3512:DZY Loves Math IV

    传送门 Sol 好神仙的题目.. 一开始就直接莫比乌斯反演然后就 \(GG\) 了 orz 题解 permui 枚举 \(n\),就是求 \(\sum_{i=1}^{n}S(i,m)\) 其中\(S( ...