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


    阻塞队列 用在哪?

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

    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() + "	" + 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() + "	" + 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();
    
        }
    }
    

     

  • 相关阅读:
    Leetcode: Increasing Triplet Subsequence
    Snapchat面经(师兄的)
    M面经prepare: Shuffle a deck
    M面经Prepare: Find integer Average of 2 integers.
    M面经Prepare: Positive-Negative partitioning preserving order
    M面经Prepare: Delete Words Starting With One Character
    Lintcode: Subtree
    Leetcode: Reconstruct Itinerary
    Groupon面经:Find paths in a binary tree summing to a target value
    一些小感悟(2014.04版)
  • 原文地址:https://www.cnblogs.com/xhyouyou/p/12465313.html
Copyright © 2020-2023  润新知