本文共 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/