线程间通讯之【生产者&消费者】模型

  • 同步:线程间通讯要确保同步执行;
  • 同锁:线程间同步机制锁需要是同一个对象,才能保证同步,可以通过synchronized关键字或Lock来实现;
  • 轮询:通过while或其他循环方法来获取当前状态,是该等待还是通知对方;
  • 通讯:所谓的通讯其实是通过共用锁的waitnotify方法来实现的;

商品对象类

/**
 * 商品描述类,当前只是简单地标记商品的有与无
 */
public class Goods {
    // 是否还有库存
    boolean isEmpty;

    public Goods() {
        this.isEmpty = true;
    }
}

消费者

/**
 * 消费者模型
 */
public class Consumer extends Thread {
    Goods goods;

    public Consumer(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        // 循环检测
        while (true) {
            // 同步执行
            synchronized (goods) {
                // 如果库存不为空则开始消费,消费结束后,将库存标记为空
                if (!goods.isEmpty) {
                    System.out.println("---------------------");
                    System.out.println("消费");
                    try {
                        Thread.sleep(1000);
                        System.out.println("...");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("需求");
                    goods.isEmpty = true;
                }
                // 通知生产,当前线程等待,直接到生产唤醒
                goods.notify();
                try {
                    goods.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

生产者

/**
 * 生产者模型
 */
public class Producer extends Thread {
    Goods goods;

    public Producer(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (goods) {
                // 如果库存标记为空则开始生产,生产结束后,将库存标记修改为非空
                if (goods.isEmpty) {
                    System.out.println("+++++++++++++++++++++");
                    System.out.println("生产");
                    try {
                        Thread.sleep(1000);
                        System.out.println("...");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println("提供");
                    goods.isEmpty = false;
                }
                // 通知消费并且当前线程处于等待,直到被消费唤醒
                goods.notify();
                try {
                    goods.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

调用

    public static void main(String[] args) {
        Goods goods = new Goods();
        Consumer consumer = new Consumer(goods);
        Producer producer = new Producer(goods);
        consumer.start();
        producer.start();
    }

运行结果

+++++++++++++++++++++
生产
...
提供
---------------------
消费
...
需求
+++++++++++++++++++++
生产
...
提供
---------------------
消费
...
需求

Leave a Reply