前面一篇文章《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. ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第五天(非原创)

    文章大纲 一.课程介绍二.前台系统(门户系统)搭建介绍三.前台系统(门户系统)搭建实战四.js请求跨域解决五.项目源码与资料下载六.参考文章   一.课程介绍 一共14天课程(1)第一天:电商行业的背 ...

  2. 前端缓存-IndexedDB

    IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作.IndexedDB 允许储存大量数据,提供查找接口,还能建立索引.这些都是 LocalStorage 所不具备的.就数据库类 ...

  3. poj3368 Frequent values

    思路: 转化为RMQ. 实现: #include <cstdio> #include <cstring> #include <algorithm> using na ...

  4. 用unsigned char 表示字节

    在C中,默认的基础数据类型均为signed,现在我们以char为例,说明(signed) char与unsigned char之间的区别 首先在内存中,char与unsigned char没有什么不同 ...

  5. 新浪qq登录

    一:到腾讯QQ互联上申请APPID和APPKEY.申请地址: http://connect.qq.com/ 如同,这里我们可以获取到需要跳转到的APPID和APPKEY.新浪微博的申请同理 二:在Th ...

  6. Scala基础篇-02函数与代码块

    1.block 代码块也是表达式,其最终求得的值是最后一个表达式的值. {exp1;exp2} { exp1 exp2 } 2.function def funtionName(param:Param ...

  7. [Windows Server 2008] 搭建数据云备份

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:如何搭建数 ...

  8. 数据库和java的类型转化

    mysql 的转化 count(1)   返回类型是bigint  对应的java 是 BigInteger cast(sum(name) as char)    sum转化为字符串

  9. hystrix 解决服务雪崩效应

    1.服务雪崩效应 默认情况下tomcat只有一个线程池去处理客户端发送的所有服务请求,这样的话在高并发情况下,如果客户端所有的请求堆积到同一个服务接口上, 就会产生tomcat的所有线程去处理该服务接 ...

  10. css 动态导入css文件 @import 动态js加载 都是静态的

    @import "http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css" /*-防止各大cdn公共库加载地址失效 ...