阻塞队列-生产者-消费者的传统模式

阻塞队列 用在哪?

  • 生产者消费者模式 
    传统版 
    阻塞队列版
  • 线程池
  • 消息中间件

1、传统线程生产者-消费者模式是什么?

image

2、传统生产者-消费者模式代码验证2.0版本

判断使用while不会出现虚假唤醒问题

/**
 * Lock 传统生产者-消费者模式 代码验证2.0版本
 * @Author小海
 * @Description:
 * @Date: Create in 20:03 2020-02-01
 */
public class ShareData {
    private int num = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    /**
     * 加法操作+1
     */
    public void increment(){
        lock.lock();
        try {
            // 防止虚假唤醒机制
            while (num != 0){
            // if (num != 0){
                // 生产者线程等待生产
                condition.await();
            }
            // 生产者线程进行生产操作
            num++;
            System.out.println(Thread.currentThread().getName() + "\t" + num);
            // 生产者线程通知唤醒消费者线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 减法操作+1
     */
    public void decrement(){
        lock.lock();
        try {
            while (num == 0){
                // 消费者线程等待消费
                condition.await();
            }
            // 消费者线程进行消费操作
            num--;
            System.out.println(Thread.currentThread().getName() + "\t" + num);
            // 消费者线程通知唤醒生产线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
      * 面试题目:一个初始值为0的变量,两个线程对其交替操作,一个加1,一个减1,交替循环5 * 传统模式的生产者和消费者Demo
      * 1、线程操作资源共享类ShareData
      * 2、线程判断(while)是否执行加减操作
      * 3、线程操作完成之后,需要通知(condition.signalAll())其他线程
      * 4、防止虚假唤醒机制(if和while使用哪个?当然是使用while来判断)
      */
    public static void main(String[] args) {
        ShareData shareData = new ShareData();
        // 线程t1进行加法操作
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                shareData.increment();
            }
        }, "t1").start();

        // 线程t2进行减法操作
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                shareData.decrement();
            }
        }, "t2").start();

        // 线程t3进行加法操作
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                shareData.increment();
            }
        }, "t3").start();

        // 线程t4进行减法操作
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                shareData.decrement();
            }
        }, "t4").start();

    }
}

 

posted @ 2019-09-11 13:34  要好好吃饭  阅读(227)  评论(0编辑  收藏  举报