1.wait/notifyAll

/**
* 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,
* 能够支持2个生产者线程以及10个消费者线程的阻塞调用
*
* 使用wait和notify/notifyAll来实现
*
* @author cx
*/
package com.chanx.demo.example.c_021; import java.util.LinkedList;
import java.util.concurrent.TimeUnit; public class MyContainer1<T> {
final private LinkedList<T> lists = new LinkedList<>();
final private int MAX = 10; //最多10个元素
private int count = 0; public synchronized void put(T t) {
while(lists.size() == MAX) { //想想为什么用while而不是用if?
try {
this.wait(); //effective java
} catch (InterruptedException e) {
e.printStackTrace();
}
} lists.add(t);
++count;
this.notifyAll(); //通知消费者线程进行消费
} public synchronized T get() {
T t = null;
while(lists.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t = lists.removeFirst();
count --;
this.notifyAll(); //通知生产者进行生产
return t;
} public static void main(String[] args) {
MyContainer1<String> c = new MyContainer1<>();
//启动消费者线程
for(int i=0; i<10; i++) {
new Thread(()->{
for(int j=0; j<5; j++) System.out.println(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();
}
}
}

2.Lock/Condition

/**
* 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,
* 能够支持2个生产者线程以及10个消费者线程的阻塞调用
*
* 使用wait和notify/notifyAll来实现
*
* 使用Lock和Condition来实现
* 对比两种方式,Condition的方式可以更加精确的指定哪些线程被唤醒
*
* @author cx
*/
package com.chanx.demo.example.c_021; import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class MyContainer2<T> {
final private LinkedList<T> lists = new LinkedList<>();
final private int MAX = 10; //最多10个元素
private int count = 0; private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();
private Condition consumer = lock.newCondition(); public void put(T t) {
try {
lock.lock();
while(lists.size() == MAX) { //想想为什么用while而不是用if?
producer.await();
} lists.add(t);
++count;
consumer.signalAll(); //通知消费者线程进行消费
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public T get() {
T t = null;
try {
lock.lock();
while(lists.size() == 0) {
consumer.await();
}
t = lists.removeFirst();
count --;
producer.signalAll(); //通知生产者进行生产
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return t;
} public static void main(String[] args) {
MyContainer2<String> c = new MyContainer2<>();
//启动消费者线程
for(int i=0; i<10; i++) {
new Thread(()->{
for(int j=0; j<5; j++) System.out.println(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();
}
}
}

生产者消费者两种实现:wait/notifyAll和Lock/Condition的更多相关文章

  1. 生产者消费者模式-Java实现

    感知阶段 随着软件业的发展,互联网用户的日渐增多,并发这门艺术的兴起似乎是那么合情合理.每日PV十多亿的淘宝,处理并发的手段可谓是业界一流.用户访问淘宝首页的平均等待时间只有区区几秒,但是服务器所处理 ...

  2. Java多线程_生产者消费者模式1

    生产者消费者模型       具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品.生产消费者模式如下图.(图片来自网络 ...

  3. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  4. Java实现多线程生产者消费者模式的两种方法

    生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据.生产者生产一个,消费者消费一个,不断循环. 第一种实现方法,用BlockingQueue阻塞队 ...

  5. 生产者-消费者模型的3种Java实现:synchronized,signal/notifyAll及BlockingQueue

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3555111.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

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

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

  7. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  8. 生产者消费者问题Java三种实现

    生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...

  9. 多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

随机推荐

  1. gulp安装和使用

    1.全局安装gulp:sudo npm install -g gulp 2.代码根目录:npm install 3.gulp 开始编译(在项目根目录下创建一个名为 gulpfile.js 的文件) 注 ...

  2. 【转载三】Grafana系列教程–Grafana的配置及运行

    本篇文章,就让我们来了解下,Grafana的简单配置及运行. 详细的配置我们后面会讲,本篇文章只对其配置做一个简单了解,主要是让大家了解Grafana的配置及启动的过程及方法. 更多Grafana问题 ...

  3. 怎么搜索sci论文。

    进入清华大学图书馆,选择常用数据库,找到 Web of Science平台(SCI/SSCI/AHCI.ISTP/ISSHP.DII.JCR.BP.CCC.CCR/IC.ESI.INSPEC…)即可. ...

  4. SQL-26 (二次分组)汇总各个部门当前员工的title类型的分配数目,结果给出部门编号dept_no、dept_name、其当前员工所有的title以及该类型title对应的数目count

    题目描述 汇总各个部门当前员工的title类型的分配数目,结果给出部门编号dept_no.dept_name.其当前员工所有的title以及该类型title对应的数目countCREATE TABLE ...

  5. Centos7初始配置

    配置 centos7 ip地址: vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=static ONBOOT=yes NM_CONTRO ...

  6. 组队项目——黄金点(叶雨&王浩)

    代码来源:自己编写 运行环境:win10 编译软件:VC++6.0 使用语言:C语言 功能:可多次运行,由用户决定退出与否,可以记录玩家的姓名与分数并显示. BUG:暂未发现 GitHub地址:htt ...

  7. jmeter中添加压力机

    在压测的时候,可能并发比较大,一台机子已经启动不了那么多并发了,这个时候就是有多台机子一起来并发,就要添加压力机 如何添加压力机呢: 1.其他电脑上也安装了jmeter,和其他电脑都能ping通当前电 ...

  8. matlab xml文件交互

    xml文件以文档对象模型表示,简称DOM(Document Object Model).在Matlab中,使用xmlread读取xml文件成DOM节点,对xml文件的操作转化成对DOM节点的操作,使用 ...

  9. JAVA_全局配置文件(配置网址,url等等)_第二种方式

    @ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中 1.application-local.yml 配置文件 2.Service 3. ...

  10. swift3.0 自定义键盘

    ...绕了一大圈,又绕回原生来了,今天,学习一下swift3.0语法下的自定义键盘.效果图如下: 其实,很简单,只需要把UITextView(或者UITextField)的inputView属性设置为 ...