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 ...
随机推荐
- Django之中间件、缓存以及信号
Django之中间件 中间件执行流程 我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下: 也就是说,每一个请求都是先通 ...
- PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)
1053 Path of Equal Weight (30 分) Given a non-empty tree with root R, and with weight Wi assigne ...
- Java使用Apache Commons Exec运行本地命令行命令
首先在pom.xml中添加Apache Commons Exec的Maven坐标: <!-- https://mvnrepository.com/artifact/org.apache.comm ...
- web前端学习路程
学习路程: 1.HTML和CSS基础 2.JavaScript语言 3.jQuery and ajax 4.综合网站实践 5.优化及调试
- 关于opencv的几个小总结
关于opencv的几个小总结 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:opencv是一个非常好用的开源图像处理与计算机视觉支持库,但是在实际使用 ...
- JS通过ActiveX读写ini配置文件
String.prototype.trim = function(){ return this.replace(/(^\s+)|(\s+$)/g, ''); }; IniConfig = functi ...
- JS CSS写下拉菜单 竖行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 遇到引入的JS不起作用
1.js的加载是有先后顺序的,并且不能重复引入,重复引入的只有最后一个起作用 2.在使用ligerUI的时候一定要先引用jQuery再引用ligerUI 3.在使用jQuery时遇到变量名未定义的主要 ...
- CardView的使用(可以实现圆角控件)
简介:ardView继承自FrameLayout,它是一个带圆角背景和阴影的FrameLayout 一些什么实现方式就不赘述了,直接上用法 CardView的常用属性 1.设置背景颜色 app: ...
- 洛谷 题解 P3627 【[APIO2009]抢掠计划】
图论 tarjan缩点+最短路 的一道题 tarjan求强连通分量(为以后缩点打下良好的基础) (如果不会tarjan的请点击这儿) 你需要的东西: (1).dfn[],表示这个点在dfs时是第几个被 ...