博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReentrantLock与Condition实现生产者消费者,模拟延时用LockSupport.parkNanos
阅读量:2059 次
发布时间:2019-04-29

本文共 2819 字,大约阅读时间需要 9 分钟。

使用ReentrantLock与Condition实现生产者消费者

主要有Producer,Consumer,Pool 生产池

在测试多线程程序时,最后【多建线程】才能明显看出并发时,是否数据异常。建议10到30个线程
创建的线程数少,模拟的延时太高,多线程可能会依次执行,不能判断是否线程安全

Pool生产池,封装也生产与消费的方法,注意里面的【while循环】判断Pool是否满或者空,负责会产出线程安全,过满或负数超消费问题

import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.LockSupport;import java.util.concurrent.locks.ReentrantLock;/** * @author zhanghui * @date 2019/5/10 */public class ProducerConsumerSolutionUsingLock {    public static void main(String[] args) {        Pool pool = new Pool();        for(int i=0;i<30;i++){            Producer p = new Producer(pool);            p.setName("p"+i);            p.start();        }        for(int i=0;i<20;i++){            Consumer c = new Consumer(pool);            c.setName("c"+i);            c.start();        }    }}// share objectclass Pool{    private int capacity=200;    private int goods=0;    private final ReentrantLock lock = new ReentrantLock(true);    private final Condition plock = lock.newCondition(); //Producer lock    private final Condition clock = lock.newCondition(); //Consumer lock    public void produceGoods(int newGoods) {        lock.lock();        try {            while (goods+newGoods>=capacity){                System.out.println("full:"+Thread.currentThread().getName());                plock.await();            }            int before = goods;            goods+=newGoods;            System.out.println("Producer:"+Thread.currentThread().getName()+" before "+before+",after "+goods);            clock.signalAll();        } catch (InterruptedException e) {            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void consumeGoods(int oldGoods) {        lock.lock();        try {            while(goods-oldGoods<=0){                System.out.println("empty:"+Thread.currentThread().getName());                clock.await();            }            int before = goods;            goods-=oldGoods;            System.out.println("Consumer:"+Thread.currentThread().getName()+" before "+before+",after "+goods);            plock.signalAll();        } catch (InterruptedException e) {            e.printStackTrace();        }finally {            lock.unlock();        }    }}class Producer extends Thread {    private Pool pool;    public Producer(Pool pool){        this.pool=pool;    }    @Override    public void run() {        while (true){            pool.produceGoods(5);            LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));        }    }}class Consumer extends Thread {    private Pool pool;    public Consumer(Pool pool){        this.pool=pool;    }    @Override    public void run() {        while (true){            pool.consumeGoods(3);            LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));        }    }}

转载地址:http://oyalf.baihongyu.com/

你可能感兴趣的文章
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>
【托业】【新东方全真模拟】01~02-----P5~6
查看>>
【托业】【新东方全真模拟】03~04-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST05~06-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST09~10-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST07~08-----P5~6
查看>>
solver及其配置
查看>>
JAVA多线程之volatile 与 synchronized 的比较
查看>>
Java集合框架知识梳理
查看>>
笔试题(一)—— java基础
查看>>
Redis学习笔记(二)— 在linux下搭建redis服务器
查看>>
Redis学习笔记(三)—— 使用redis客户端连接windows和linux下的redis并解决无法连接redis的问题
查看>>
Intellij IDEA使用(一)—— 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
查看>>
Intellij IDEA使用(二)—— 在Intellij IDEA中配置JDK(SDK)
查看>>
Intellij IDEA使用(三)——在Intellij IDEA中配置Tomcat服务器
查看>>
Intellij IDEA使用(四)—— 使用Intellij IDEA创建静态的web(HTML)项目
查看>>
Intellij IDEA使用(五)—— Intellij IDEA在使用中的一些其他常用功能或常用配置收集
查看>>
Intellij IDEA使用(六)—— 使用Intellij IDEA创建Java项目并配置jar包
查看>>
Eclipse使用(十)—— 使用Eclipse创建简单的Maven Java项目
查看>>