用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:递归与非递归之间的转化
在常规表达式求值中: 输入为四则运算表达式,仅由数字.+.-.*./ .(.) 组成,没有空格,要求求其值. 我们知道有运算等级,从左至右,括号里面的先运算,其次是* ./,再是+.- : 这样我们就 ...
- ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第二天(非原创)
文章大纲 一.课程介绍二.整合淘淘商城ssm项目三.Mybatis分页插件PageHelper使用四.整合测试五.项目源码与资料下载六.参考文章 一.课程介绍 一共14天课程(1)第一天:电商行业 ...
- LN : leetcode 646 Maximum Length of Pair Chain
lc 646 Maximum Length of Pair Chain 646 Maximum Length of Pair Chain You are given n pairs of number ...
- [ USACO 2013 OPEN ] Photo
\(\\\) Description 有一个长度为 \(n\) 的奶牛队列,奶牛颜色为黑或白. 现给出 \(m\) 个区间 \([L_i,R_i]\) ,要求:每个区间里 有且只有一只黑牛 . 问满足 ...
- 有关HTML版本
先说说HTML的简史:从HTML1.0~2.0(1989~1991)>HTML3(1995)>HTML4(1998)>HTML4.01(1999)>XHTML1.0(2001) ...
- 田字格布局html div
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 【译】x86程序员手册35-9.8异常条件
译注:一些异常没有翻译,因为看书时主要为了理解linux代码,所以代码中没有主要使用的就没有仔细看.这部分内容后期再看时再进行翻译. 9.8 Exception Conditions 异常条件 The ...
- KMP中next数组的理解与应用
理解 1.next数组一直往前走 next数组一直往前走,得到的所有前缀也是当前主串的后缀,当然了,也是当前主串的前缀. 2.周期性字符串 1.周期性字符串$\Leftrightarrow n \,\ ...
- winpcap编程设置过滤器之指定获取某个网站的数据
下面,我将以 乱世隋唐页游 为例,通过编码获取这里面的数据. 游戏图: 我是乱世隋唐的网址是:www.917st.com 这个是官网网址的服务器地址. 42.62.0.14 我玩的游戏服是84区.网 ...
- Webpack 入门(一):安装 / 打包 / 命令行
一:安装webpack和基本环境搭建 新建一个工作的文件夹(我取的名字叫Webpack) 打开命令行,cd进入该文件夹 //初始化一下npm > E:\work\Webpack>npm i ...