用ReentrantLock和Condition实现生产者和消费者模式
前面一篇文章《wait、notify应用场景(生产者-消费者模式)》是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码:
生产者代码:
/**
* 生产者
*
* @author monkjaver
* @date 2018/12/18 22:10
*/
public class Producer implements Runnable {
/**
* 产品容器
*/
private List<Integer> container;
private Lock lock;
/**
* 生产者条件
*/
private Condition producerCondition;
/**
* 消费者条件
*/
private Condition consumerCondition; public Producer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
this.container = container;
this.lock = lock;
this.producerCondition = producerCondition;
this.consumerCondition = consumerCondition;
} public void produce() {
//产品容器容量大小
int capacity = 5;
try {
//获得锁
lock.lock();
//容器满了,不在生产
if (container.size() == capacity) {
System.out.println("生产满了。。。。");
producerCondition.await();
}
Random random = new Random();
int p = random.nextInt(50);
//模拟1秒生产一个产品
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println("生产产品:" + p);
container.add(p);
//生产一个产品,通知消费者
consumerCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
} } @Override
public void run() {
while (true) {
produce();
}
}
}
消费者代码:
/**
* @author monkjavaer
* @date 2018/12/18 22:16
*/
public class Consumer implements Runnable{
/**
* 产品容器
*/
private List<Integer> container;
private Lock lock;
/**
* 生产者条件
*/
private Condition producerCondition;
/**
* 消费者条件
*/
private Condition consumerCondition; public Consumer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
this.container = container;
this.lock = lock;
this.producerCondition = producerCondition;
this.consumerCondition = consumerCondition;
} /**
* 消费者消费产品
*/
private void consume(){
try {
//获得锁
lock.lock();
//容器大小为null,不消费
if (container.size() == 0) {
System.out.println("消费完了。。。。");
consumerCondition.await();
}
Integer p = container.remove(0);
//模拟1秒消费一个产品
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println("消费产品:" + p);
//消费了,通知生产者
producerCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
@Override
public void run() {
while (true){
consume();
}
}
}
测试代码:
public class ProducerConsumerTest {
public static void main(String[] args) {
List<Integer> container = new ArrayList<>();
Lock lock = new ReentrantLock();
Condition producerCondition = lock.newCondition();
Condition consumerCondition = lock.newCondition();
Thread producer = new Thread(new Producer(container,lock,producerCondition,consumerCondition));
Thread consumer = new Thread(new Consumer(container,lock,producerCondition,consumerCondition));
producer.start();
consumer.start();
}
}
ReentrantLock 公平锁和非公平锁
非公平锁:获取锁的方式是抢占式的,随机的。默认ReentrantLock()是非公平的。jdk1.8源码如下:
public ReentrantLock() {
sync = new NonfairSync();
}
公平锁:线程获取锁的顺序是按照线程加锁的顺序来分配的。ReentrantLock(true)是公平的。jdk1.8源码如下:
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
用ReentrantLock和Condition实现生产者和消费者模式的更多相关文章
- condition版生产者与消费者模式
1.简介 在爬虫中,生产者与消费者模式是经常用到的.我能想到的比较好的办法是使用redis或者mongodb数据库构造生产者消费者模型.如果直接起线程进行构造生产者消费者模型,线程容易假死,也难以构造 ...
- ReentrantLock和Condition实现生产者和消费者
一个生产者和一个消费者 public class ConditionTest { private static ReentrantLock lock = new ReentrantLock(); pr ...
- 【爬虫】Condition版的生产者和消费者模式
Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...
- Java并发编程(4)--生产者与消费者模式介绍
一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...
- 使用libuv实现生产者和消费者模式
生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...
- java生产者与消费者模式
前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...
- Java多线程设计模式(2)生产者与消费者模式
1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...
- 【爬虫】Load版的生产者和消费者模式
''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...
- java 线程并发(生产者、消费者模式)
线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...
随机推荐
- AJPFX总结JAVA基本数据类型
1:关键字(掌握) (1)被Java语言赋予特定含义的单词 (2)特点: 全部小写. (3)注意事项: ...
- vue项目中安装cnpm和node_modules
1.安装cnpm的nodejs包管理工具,命令行: npm install -g cnpm --registry=https://registry.npm.taobao.org 2. 每个vue项 ...
- js跨域请求的5中解决方式
跨域请求数据解决方案主要有如下解决方法: ? 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分开说明: 一.J ...
- CCF|游戏|Java
import java.util.Scanner; public class tyt { public static void main(String[] args) { Scanner in = n ...
- sql发送邮件- html 格式
ALTER PROCEDURE dbo.sx_pro_AutoEmailContent AS Begin declare @Rqty int declare @n int declare @m_rec ...
- 3D旋转矩阵的推导过程
3D旋转矩阵的推导过程 包含平移的线性变换称作仿射变换,3D中的仿射变换不能用 3 x 3 矩阵表达,必须使用4 x 4矩阵. 一般来说,变换物体相当于以相反的量变换描述这个物体的坐标系.当有多个变换 ...
- 使用Latex插入数学公式(二)
初级运算 关系运算符 希腊字母 集合运算符逻辑运算符 空格问题 矩阵格式 矩阵格式有三种: 无括号的矩阵 matrix 是 Latex 的矩阵命令,矩阵命令中每一行以 \\ 结束,矩阵的元素之间用 & ...
- crontab 每月最后一天执行命令
没有什么是解决不了的事情,如果有,只是我们的知识不够精通,学得不扎实 需求:有一个程序,需要在每个月的最后一天执行 例如:每个月的最后一天早上8:00 打印 dede 到 /tmp/test.txt ...
- linux crontab创建计划任务
1.编辑计划任务 编辑crontab文件 crontab -e 2.查看计划任务日志 查看crontab日志 tail -100f /var/log/cron 3.创建计划任务格式 (1)基本格式 : ...
- freenas 系统可能存在的bug
1.portal 中ip端口显示有问题. 2.创建extend/target映射之后重启iscsi服务有的时候不能启动. 3.后台/usr /etc 重启系统会自动还原.