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 ...
随机推荐
- VCL组件之TPanel
TPanel位于Standard组件面板上,也是常用的一种容器控件.面板的一个优点就是放在面板上的组件称为面板的一部分,因此它们与面板一起移动.这在设计阶段很有用. Panel组件的大部分功能在于其A ...
- PHP重建数组的索引
sort() array_merge()跟一个空数组合并都可以重建索引数组的键(key)
- Dapper存储过程以及多次查询和批量写入操作
一.存储过程操作 1. 准备存储过程 newsreturnvalue(该存储过程计算2个参数的和并返回) USE [ZPC.Contact] GO SET ANSI_NULLS ON GO SET Q ...
- kotlin基本数据类型
通过idea创建kotlin项目: 创建kotlin文件 package com.czhappy.chapter01 var aBoolean:Boolean = true var anInt:Int ...
- eNSP——静态路由的基本配置
原理: 静态路由是指用户或网络管理员手工配置的路由信息.当网络的拓扑结构或链路状态发生改变时,需要网络管理人员手工修改静态路由信息. 相比于动态路由协议,静态路由无需频繁地交换各自的路由表,配置简单, ...
- python 模块import(26)
一.模块简介 python开发中,每一个.py文件都可以看作是一个模块,模块内部的函数或者方法可以被其他模块调用,至于函数或者方法是具体如何实现的,调用者不需要关心. 假如项目中既含有UI也有逻辑代码 ...
- opencv根据摄像头名称获取索引值
OpenCV的VideoCapture是一个视频读取与解码的API接口,支持各种视频格式.网络视频流.摄像头读取. 针对一般摄像头的读取,opencv为了实现跨平台读取摄像头时是使用的摄像头索引, V ...
- 图说socket与系统调用代码架构
1.引言 正式开始之前,每个人心里都应该有一点逼数,就像下面这张图一样. 系统调用也是函数调用,系统函数也是函数代码.系统函数与普通函数唯一的不同在于,系统函数可以使用cpu体系结构指令集中的特权指令 ...
- v-radio
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- spring-cloud项目搭建
springCloud项目搭建手册 springcloud应用场景及微服务框架发展趋势 Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断 ...