Java并发案例02---生产者消费者问题
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---生产者消费者问题的更多相关文章
- 使用Java的BlockingQueue实现生产者-消费者
http://tonl.iteye.com/blog/1936391 使用Java的BlockingQueue实现生产者-消费者 博客分类: Java JavaBlockingQueue阻塞队列 B ...
- Java并发案例03---生产者消费者问题02
生产者消费者第二种情形 package com.maple.msb.one; public class ProducerConsumer { public static void main(Strin ...
- java 多线程并发系列之 生产者消费者模式的两种实现
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...
- JAVA并发实现五(生产者和消费者模式wait和notify方式实现)
package com.subject01; import java.util.PriorityQueue; /** * 通过wait和notify 实现 * 生产者-消费者模型:当队列满时,生产者需 ...
- JAVA多线程经典问题 -- 生产者 消费者
工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...
- 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型
本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...
- Java多线程14:生产者/消费者模型
什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...
- Java 管程解决生产者消费者问题
同样是实验存档.//.. 依然以生产者消费者问题作为背景. 管程(=“资源管理程序”)将资源和对资源的操作封装起来,资源使用者通过接口操作资源就 ok,不用去考虑进程同步的问题. 管程: packag ...
- day34 并发编程之生产者消费者模型 队列
1.守护进程(了解) """ 守护进程 表示 一个进程b 守护另一个进程a 当被守护的进程a结束后 那么b也跟着结束了 就像 皇帝驾崩 妃子殉葬 应用场景 之所以开启子进 ...
- java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现
java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了 wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...
随机推荐
- JS实现最小生成树之克鲁斯卡尔(Kruskal)算法
克鲁斯卡尔算法打印最小生成树: 构造出所有边的集合 edges,从小到大,依次选出筛选边打印,遇到闭环(形成回路)时跳过. JS代码: //定义邻接矩阵 let Arr2 = [ [0, 10, 65 ...
- 【转】Windows 平台下 Go 语言的安装和环境变量设置
1. Go 语言 SDK 安装包下载和安装 最新稳定版 1.5.3 安装包 go1.5.3.windows-amd64.msi下载地址 https://golang.org/dl/,大小约 69 MB ...
- 面向对象(基础oop)之结构与数组高级
大家好,我叫李京阳,,很高兴认识大家,之所以我想开一个自己的博客,就是来把自己所了解的知识点通过自己的话写一下,希望被博客园的朋友们点评和一起讨论一下,也希望从博客园中多认识一些软件开发人员!现在我开 ...
- java中的奇葩 “:”
一.经常使用java的人有没有发现java也可以将汉字作为标识符出现呢? 在Java语言中,标识符是以字母.下划线(_)或美元符($)开头,由字母.数字.下划线(_)或美元符($)组成的字符串 真的输 ...
- 一键安装lamp环境出现的问题
前言:之前安装lamp是独立安装的,安装扩展很方便,现在用这个一键安装包,不知道怎么样,尝试一把. Part1:安装过程中出现的问题 error: utf8_mime2text() has new s ...
- K:顺序表和链表的比较
顺序表和链表是线性表的两种基本实现形式(链表还有多种变化形式),对于这两种实现方式,没有一种方法可以称是最好的,他们各自有着各自的特点和优缺点,适用于不同的应用场景. 与顺序表相比,链表较为灵活, ...
- css 各种常见布局整理
在学习各种布局之前我们先来认识各个关键词,理解这些关键词,然后由点到面,这样就简单多了. display属性 页面中每个元素都有一个默认的display属性,它的值与该元素的类型有关,默认值通常是 b ...
- DOM操作表单(select下拉选框)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- MySQL5.5登陆
通过cmd登陆 mysql -h localhost -P 3306 -u root -p123456 h后面跟的是域名或IP地址:大写的P后面跟的是端口号:u后面跟的是用户名:小写的p后面跟的是密码 ...
- AngularJS+RequireJs实现动态加载JS和页面的方案研究【上】
1.入口页面 存放地址:src/main/webapp/WEB-INF/view/workflow/workflow.jsp [html] view plain copy 在CODE上查看代码片派生到 ...