Condition producers and consumers to achieve ReentrantLock, analog delay with LockSupport.parkNanos

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/c5113620/article/details/90079909

Use ReentrantLock producers and consumers realize Condition

There are Producer, Consumer, Pool production pool
when testing multithreaded programs, and finally [thread] to build more evident when concurrency, whether the data is abnormal. Recommend 10-30 threads
threads created by a small number of analog delay is too high, multi-threaded execution may in turn, can not determine whether thread safety

Pool pool production, packaging production methods and consumption also, [Note] inside the while loop Pool determine whether full or empty, the output will be responsible for the security thread, too full or negative super-consumption problem


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 object
class 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));
        }
    }
}

Guess you like

Origin blog.csdn.net/c5113620/article/details/90079909