java Lock-condition 模拟生产者消费者模式


/**
 * Condition putCondition = lock.newCondition();//实例
 * putCondition.await();//与Object.wait方法一样,都是要与while共同使用,使线程等待,释放锁,
                          直到putCondition.signal()或putCondition.signalAll()才继续执行
 * putCondition.signal();//唤醒 putCondition.await() 等待的线程
 *
 *  Lock 的 condition 进行 模拟 生产者和消费者 模式
 *  模拟 生产者 的仓库最大是3,大于3之后,只有等消费者消费完后才能进行生产
 *  消费者需要等仓库有东西之后,才能进行消费
 */
public class LockConditionTest {
    Lock lock = new ReentrantLock();
    private Condition putCondition = lock.newCondition();
    private Condition popCondition = lock.newCondition();

    private List<Integer> dataList = new ArrayList<>();//仓库

    /**
     * 生产者方法
     */
    public void put(){
        try {
            lock.lock();
            while (dataList.size() >= 3){
                System.out.println("仓库数量超过3,不能进行生产 size:"+dataList.size());
                putCondition.await();
                System.out.println("生产者被唤醒");
            }
            dataList.add(dataList.size() + 1);
            System.out.println("生产者生产 1 个商品,当前 仓库 size:"+dataList.size());
            popCondition.signalAll();//通知消费者 消费
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    /**
     * 消费者方法
     */
    public void pop(){
        try {
            lock.lock();
            while (dataList.size() == 0 ){
                System.out.println("仓库无商品,不能进行消费 size:"+dataList.size());
                popCondition.await();
                System.out.println("消费者被唤醒");
            }
            dataList.remove(0);
            System.out.println("消费者消费1个商品,当前 仓库 size:"+dataList.size());
            putCondition.signalAll();//通知生产者生产
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        LockConditionTest test = new LockConditionTest();
        //生产者线程 1
        new Thread(()->{
            while (true) {
                try {
                    Thread.sleep(1000);
                    test.put();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //生产者线程 2
        new Thread(()->{
            while (true) {
                try {
                    Thread.sleep(1000);
                    test.put();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        //消费者线程 1
        new Thread(()->{
            while (true) {
                try {
                    Thread.sleep(2000);
                    test.pop();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //消费者线程 2
        new Thread(()->{
            while (true) {
                try {
                    Thread.sleep(2000);
                    test.pop();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

运行结果:

生产者生产 1 个商品,当前 仓库 size:1
生产者生产 1 个商品,当前 仓库 size:2
消费者消费1个商品,当前 仓库 size:1
消费者消费1个商品,当前 仓库 size:0
生产者生产 1 个商品,当前 仓库 size:1
生产者生产 1 个商品,当前 仓库 size:2
生产者生产 1 个商品,当前 仓库 size:3
仓库数量超过3,不能进行生产 size:3
消费者消费1个商品,当前 仓库 size:2
消费者消费1个商品,当前 仓库 size:1
生产者被唤醒
生产者生产 1 个商品,当前 仓库 size:2
生产者生产 1 个商品,当前 仓库 size:3
仓库数量超过3,不能进行生产 size:3
仓库数量超过3,不能进行生产 size:3
消费者消费1个商品,当前 仓库 size:2
消费者消费1个商品,当前 仓库 size:1
生产者被唤醒

发布了60 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/xiaoluo5238/article/details/104359334