首页 > 编程语言 > 详细

生产者消费者模型Java实现

时间:2019-06-10 14:02:16      阅读:89      评论:0      收藏:0      [点我收藏+]

生产者消费者问题是研究多线程程序时绕不开的经典问题之一。

问题描述如下。使用一个商品的缓存池用来存放商品。当池子满时,生产者不能往池子里加入商品;当池子空时,消费者不能从池子中取得商品。


使用Object的方法 wait() notify()/notifyAll()实现

获取锁和释放锁都是针对Object而言的,而和线程无关。试想如果和线程相关,那么一个线程就无法使用多个锁。

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Pool {

    private int MAX;
    private int cnt = 0;

    public Pool(int MAX) {
        this.MAX = MAX;
    }

    public synchronized void produce() throws InterruptedException {
        while (cnt == MAX) {
            wait();
        }
        System.out.println("Produce one.. Now:" + ++cnt);
        notify();
    }

    public synchronized void consume() throws InterruptedException {
        while (cnt == 0) {
            wait();
        }
        System.out.println("Consume one.. Now:" + --cnt);
        notifyAll();
    }

    public static void main(String[] args) {
        Pool pool = new Pool(6);
        Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executor.execute(() -> {
                try {
                    pool.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        for (int i = 0; i < 10; i++) {
            executor.execute(() -> {
                try {
                    pool.consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

使用 wait() notify()/notifyAll()的缺点在于在生产者唤醒消费者或者消费者唤醒生产者时,由于生产者和消费者使用同一个锁,所以生产者也会将生产者唤醒,消费者也会将消费者唤醒。(这一点也被字节跳动的面试官问到啦TAT)

Condition可以指定多个等待的条件,因此使用Condition可以解决这一问题。


使用ReentrantLock和Condition的await() signal()/signalAll()实现

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Pool {

    private int MAX;
    private int cnt = 0;
    private ReentrantLock lock = new ReentrantLock();
    private Condition produce = lock.newCondition();
    private Condition consume = lock.newCondition();

    public Pool(int MAX) {
        this.MAX = MAX;
    }

    public void produce() throws InterruptedException {
        lock.lock();
        try {
            while (cnt == MAX) {
                produce.await();
            }
            System.out.println("Produce one.. Now:" + ++cnt);
            consume.signal();
        } finally {
            lock.unlock();
        }
    }

    public void consume() throws InterruptedException {
        lock.lock();
        try {
            while (cnt == 0) {
                consume.await();
            }
            System.out.println("Consume one.. Now:" + --cnt);
            produce.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Pool pool = new Pool(6);
        Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executor.execute(() -> {
                try {
                    pool.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        for (int i = 0; i < 10; i++) {
            executor.execute(() -> {
                try {
                    pool.consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

 

生产者消费者模型Java实现

原文:https://www.cnblogs.com/yfzhou/p/10996801.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!