7.生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)
/*
* 生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)
* */
public class TestProductorAndConsumerForLock {
public static void main(String[] args) {
WareHouse wareHouse = new WareHouse();
Productor pd1 = new Productor(wareHouse);
Consumer cs1 = new Consumer(wareHouse); new Thread(pd1, "消费者1").start();
new Thread(cs1, "生产者1").start();
// 若有多个 生产者消费者,可能会产生虚假唤醒(缺货了,多个生产线程等待,唤醒时,这些生产线程同时醒来,对数据进行操作,这种问题叫做虚假唤醒)
// 解决办法:wait方法 尽量 使用在循环中,被唤醒之后,再去判断是否符合条件(库存是否达到上限),不符合条件
// 继续等待(等待消费者去消费商品),直到 条件符合(库存有空闲)
new Thread(pd1, "消费者2").start();
new Thread(cs1, "生产者2").start();
}
} // 仓库
class WareHouse {
// 商品数量
private int products = 0;
private ReentrantLock lock = new ReentrantLock();
//使用 Condition 的前提是 使用 Lock 同步锁,Condition 实例 实质上被绑定到一个锁上
private Condition condition = lock.newCondition(); public void set() {
lock.lock();
try {
while (products >= 1) {
System.out.println("商品库存满了");
try {
// 如果商品满了,阻塞线程,等待消费者线程消费完成后唤醒,
condition.await(); //相当于(Object.awatit() 但是功能更强大)
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("生产了商品,剩余库存" + ++products);
condition.signalAll(); //相当于 (Object.notifyAll,功能更强大)
} finally {
lock.unlock();
} } public void get() {
lock.lock();
try {
while (products <= 0) {
System.out.println("商品库存没了");
try {
// 如果商品没了,阻塞线程,等待生产者线程生产完成后唤醒,
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消费了商品,剩余库存" + --products);
condition.signalAll();
} finally {
lock.unlock();
} }
} // 生产者
class Productor implements Runnable {
private WareHouse wareHouse; public Productor(WareHouse wareHouse) {
this.wareHouse = wareHouse;
} @Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wareHouse.get();
}
} } // 消费者
class Consumer implements Runnable {
private WareHouse wareHouse; public Consumer(WareHouse wareHouse) {
this.wareHouse = wareHouse;
} @Override
public void run() {
for (int i = 0; i < 20; i++) { wareHouse.set();
}
} }
7.生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)的更多相关文章
- Condition线程通信_生产者消费者案例
①Condition 接口描述了可能会与锁有关联的条件变量. 这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能. 需要特别指出的是,单个 Lock 可能与 ...
- GUC-13 生产者消费者案例
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...
- JUC--Callable 以及Lock同步锁
/** * 一.创建执行线程的方式三:实现Callable接口.相较于实现Runnable接口方式,方法可以有返回值,并且可以抛出异常 * 二.callable 需要FutureTask实现类的支持. ...
- Lock同步锁
Lock同步锁 一.前言 在Java 5.0 之前,协调共享对象的访问时可以使用的机制只有synchronized 和volatile .Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁 ...
- (转)生产者/消费者问题的多种Java实现方式
参考来源:http://blog.csdn.net/monkey_d_meng/article/details/6251879/ 生产者/消费者问题的多种Java实现方式 实质上,很多后台服务程序并发 ...
- java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)
CPU:10核 主频100MHz 1核 主频 3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...
- Lock同步锁--线程同步
Lock-同步锁 Lock是java5提供的一个强大的线程同步机制--通过显示定义同步锁对象来实现同步.Lock可以显示的加锁.解锁.每次只能有一个线程对lock对象加锁. Lock有ReadLock ...
- 深入分析 Java Lock 同步锁
前言 Java 的锁实现,有 Synchronized 和 Lock.上一篇文章深入分析了 Synchronized 的实现原理:由Java 15废弃偏向锁,谈谈Java Synchronized 的 ...
- Java并发编程之Lock(同步锁、死锁)
这篇文章是接着我上一篇文章来的. 上一篇文章 同步锁 为什么需要同步锁? 首先,我们来看看这张图. 这是一个程序,多个对象进行抢票. package MovieDemo; public class T ...
随机推荐
- bat批处理 查找替换:批处理如何查找并替换文本里特定字符串中的部分内容
批处理如何查找并替换文本里特定字符串中的部分内容 摘自:http://www.bathome.net/thread-43349-1-1.html 脚本如下: @if()==() echo off &a ...
- 【AI教育】可以看看行业痛点分析
http://www.woshipm.com/it/2801582.html 至于解决方案嘛,还在堆砌技术的阶段.
- Python 爬虫从入门到进阶之路
https://www.cnblogs.com/weijiutao/p/10735455.html
- 腾讯ios内部视频,什么垃圾视频
前几天朋友在网上花钱买了个,腾讯ios内部视频,我也跟着下载了, 看着这列表,我感觉没什么东西,一看就是基础的东西,完全没有实战的内容,就像培训机构骗学生的东西啊,讲些毛理论,结果一到实战了,问个Sc ...
- preg_replace修饰符e的用法
$tmp_refer = postget('refer');$tmp_refer = preg_replace("/tn-(.*?).html/ies", "'tn-'. ...
- CareerCup Questions List 职业杯题目列表
网站 www.careercup.com 上的题库列表 # Title Difficulty Company 1 Guards in a museum Hard F, G 2 Bomberman H ...
- CentOS 7 安装wordpress
1.安装php 要安装php 7,必须使用下面的命令在Centos7系统上安装并启用epel和remi存储库. 输入一下代码, yum install http://rpms.remirepo.net ...
- mysql 表字段部分替换
update user set `ph` = REPLACE(`ph`,'shenji.osnt.me','60.210.113.147:555');
- 99%的人都理解错了GET与POST的区别
原文链接:https://mp.weixin.qq.com/s?__biz=MzI3NzIzMzg3Mw==&mid=100000054&idx=1&sn=71f6c214f3 ...
- Python中最常见的10个问题(列表)
列表是Python中使用最多的一种数据结果,如何高效操作列表是提高代码运行效率的关键,这篇文章列出了10个常用的列表操作,希望对你有帮助. 1.迭代列表时如何访问列表下标索引 普通版: items = ...