生产者和消费者模型

Object中有两个涉及到了线程的方法:

  • void wait():让当前线程进入等待状态,直到被唤醒;(会释放锁)
  • void notify():唤醒当前正在等待的线程。(只会通知,不会释放锁)

因为Object是所有类的鼻祖,所以每一个对象都拥有wait()和notify()。

生产者和消费者模型

上述两个方法可以引出生产者和消费者模型:一种特定需求。

注:生产者和消费者都是不停的生产和消费。

假设有一个list容器,只能存放一个数据,为空时,生产者生产一个数据,有一个数据时,消费者消费该数据:

可以用wait()和notify()建立在synchronized上,解决生产者和消费者模型中的线程安全问题。

package com.dh.model;

import java.util.ArrayList;
import java.util.List;

public class Thread01 {
    public static void main(String[] args) {
        List list = new ArrayList();
        //生产者线程
        Producer producer = new Producer(list);
        Thread t1 = new Thread(producer);
        t1.setName("生产者线程");
        //消费者线程
        Consumer consumer = new Consumer(list);
        Thread t2 = new Thread(consumer);
        t2.setName("消费者线程");

        t1.start();
        t2.start();
    }
}

//生产者
class Producer implements Runnable {
    //容器
    private List list;

    public Producer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            //锁住list容器
            synchronized (list) {
                //当容器中有一个数据时,生产者不再生产,即进入等待,等待消费者消费
                if (list.size() > 0) {
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //否则生产数据
                Object o = new Object();
                list.add(o);
                System.out.println(Thread.currentThread().getName()+"生产"+o);
                //容器满了之后要唤醒消费者
                list.notify();
            }
        }
    }
}

//消费者
class Consumer implements Runnable {
    //容器
    private List list;

    public Consumer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            //锁住list容器
            synchronized (list) {
                //当容器中没有数据时,消费者不能再消费,即进入等待,等待生产者生产
                if (list.size() == 0) {
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //否则生产数据
                Object o = list.remove(0);
                System.out.println(Thread.currentThread().getName()+"消费"+o);
                //容器满了之后要唤醒消费者
                list.notify();
            }
        }
    }
}

结果:只截取部分(程序会一直运行,需要手动停止)

生产者线程生产java.lang.Object@10adb5a8
消费者线程消费java.lang.Object@10adb5a8
生产者线程生产java.lang.Object@34c0842e
消费者线程消费java.lang.Object@34c0842e
生产者线程生产java.lang.Object@1d61410c
消费者线程消费java.lang.Object@1d61410c
posted @ 2021-02-23 20:20  deng-hui  阅读(348)  评论(0编辑  收藏  举报