zoukankan      html  css  js  c++  java
  • 阻塞队列-生产者-消费者的传统模式

    阻塞队列 用在哪?

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

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

     

  • 相关阅读:
    C++对象数组与对象指针
    C++析构函数
    centos7下安装mysql
    Java杂知识汇总(自己积累的)
    利用json模块解析dict报错找不到attribute 'dumps'[python2.7]
    Linux删除除了今天以外的文件
    docker简单介绍(资料收集总结)
    python不可以打印.doc文件
    python安装模块的时候报错error: command 'gcc' failed with exit status 1
    yum和head一起用,报错“由于管道被破坏而退出”
  • 原文地址:https://www.cnblogs.com/xhyouyou/p/12465313.html
Copyright © 2011-2022 走看看