前面一篇文章《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实现生产者和消费者模式的更多相关文章

  1. condition版生产者与消费者模式

    1.简介 在爬虫中,生产者与消费者模式是经常用到的.我能想到的比较好的办法是使用redis或者mongodb数据库构造生产者消费者模型.如果直接起线程进行构造生产者消费者模型,线程容易假死,也难以构造 ...

  2. ReentrantLock和Condition实现生产者和消费者

    一个生产者和一个消费者 public class ConditionTest { private static ReentrantLock lock = new ReentrantLock(); pr ...

  3. 【爬虫】Condition版的生产者和消费者模式

    Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...

  4. Java并发编程(4)--生产者与消费者模式介绍

    一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...

  5. 使用libuv实现生产者和消费者模式

    生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...

  6. java生产者与消费者模式

    前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...

  7. Java多线程设计模式(2)生产者与消费者模式

    1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...

  8. 【爬虫】Load版的生产者和消费者模式

    ''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...

  9. java 线程并发(生产者、消费者模式)

    线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...

随机推荐

  1. AJPFX总结JAVA基本数据类型

    1:关键字(掌握)        (1)被Java语言赋予特定含义的单词        (2)特点:                全部小写.        (3)注意事项:              ...

  2. vue项目中安装cnpm和node_modules

    1.安装cnpm的nodejs包管理工具,命令行: npm install -g cnpm --registry=https://registry.npm.taobao.org   2. 每个vue项 ...

  3. js跨域请求的5中解决方式

    跨域请求数据解决方案主要有如下解决方法: ? 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分开说明: 一.J ...

  4. CCF|游戏|Java

    import java.util.Scanner; public class tyt { public static void main(String[] args) { Scanner in = n ...

  5. sql发送邮件- html 格式

    ALTER PROCEDURE dbo.sx_pro_AutoEmailContent AS Begin declare @Rqty int declare @n int declare @m_rec ...

  6. 3D旋转矩阵的推导过程

    3D旋转矩阵的推导过程 包含平移的线性变换称作仿射变换,3D中的仿射变换不能用 3 x 3 矩阵表达,必须使用4 x 4矩阵. 一般来说,变换物体相当于以相反的量变换描述这个物体的坐标系.当有多个变换 ...

  7. 使用Latex插入数学公式(二)

    初级运算 关系运算符 希腊字母 集合运算符逻辑运算符 空格问题 矩阵格式 矩阵格式有三种: 无括号的矩阵 matrix 是 Latex 的矩阵命令,矩阵命令中每一行以 \\ 结束,矩阵的元素之间用 & ...

  8. crontab 每月最后一天执行命令

    没有什么是解决不了的事情,如果有,只是我们的知识不够精通,学得不扎实 需求:有一个程序,需要在每个月的最后一天执行 例如:每个月的最后一天早上8:00 打印 dede 到  /tmp/test.txt ...

  9. linux crontab创建计划任务

    1.编辑计划任务 编辑crontab文件 crontab -e 2.查看计划任务日志 查看crontab日志 tail -100f /var/log/cron 3.创建计划任务格式 (1)基本格式 : ...

  10. freenas 系统可能存在的bug

    1.portal 中ip端口显示有问题. 2.创建extend/target映射之后重启iscsi服务有的时候不能启动. 3.后台/usr /etc 重启系统会自动还原.