java wait-notify(notifyAll)实现生产者和消费者模式

 wait 让线程进入等待状态,同时释放锁,直到其它线程notify时,它才会重新运行。Object的方法,wait需要和while共用 
notify 唤醒一个线程,但是不会释放锁,如果本身拿着对象的锁,wait也不会唤醒其他线程 
 notifyAll 唤醒所有wait的线程,所以这里也是说要用wait和while搭配的原因。
/**
 *
 * 
 * wait需要和while一起使用,不能和if
 * 实现生产者和消费者模式
 * 模拟 生产者 的仓库最大是3,大于3之后,只有等消费者消费完后才能进行生产
 * 消费者需要等仓库有东西之后,才能进行消费
 */
public class WaitNotifyTest {


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

    /**
     * 生产者方法
     * 往仓库中添加一个物品,仓库大于3时,需要等待消费
     */
    public  void put(){
        try {
            synchronized(this){
                while(dataList.size() >= 3){//仓库不能超过3
                    System.out.println("大于3 等待wait listSize:"+dataList.size());
                    this.wait();//wait需要和while一起使用,不能和if
                    System.out.println("被唤醒 listSize:"+dataList.size());
                }
                dataList.add(dataList.size() + 1);
                System.out.println("生产一个 listSize:"+dataList.size());
                this.notifyAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费者方法
     * 往仓库中消费一个物品,仓库没有物品时,需要等待生产
     * 消费完之后,需要唤醒生产者
     */
    public  void pop(){
        synchronized (this){
            while (dataList.size() <= 0){
                try {
                    System.out.println("消费等待 listSize:"+dataList.size());
                    this.wait();//如果 wait的需要和 synchronize 一起使用
                    System.out.println("消费唤醒 listSize:"+dataList.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            dataList.remove(0);
            System.out.println("消费一个 listSize:"+dataList.size());
            this.notifyAll();//唤醒全部等待线程 不能用notify,如果用notify,可能只唤醒 pop这个线程
        }
    }

    public static void main(String[] args) {
        WaitNotifyTest waitNotifyTest = new WaitNotifyTest();
        System.out.println("");
        //生产者1 2秒生产1个
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(2000);
                    waitNotifyTest.put();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //生产者2 2秒生产1个
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(2000);
                    waitNotifyTest.put();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //消费者1 3秒消费1个
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(3000);
                    waitNotifyTest.pop();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        //消费者2 3秒消费1个
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(3000);
                    waitNotifyTest.pop();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
发布了60 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/xiaoluo5238/article/details/104358061
今日推荐