• 3. 生产者和消费者问题


    生产者和消费者问题:Synchronized 版

    Synchronized:wait 、notify

    package pers.vincent.matrix.subject.juc;
    
    public class JucTest3 {
        public static void main(String[] args) {
    
            NoTest noTest = new NoTest();
    
            new Thread(()->{
                for (int i = 0; i < 60; i++) {
                    try {
                        noTest.add();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "A").start();
    
            new Thread(()->{
                for (int i = 0; i < 60; i++) {
                    try {
                        noTest.del();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "B").start();
        }
    }
    
    //
    class NoTest{
    
        private int num = 0 ;
    
        public synchronized void add() throws InterruptedException {
            if(num!=0){
                this.wait();
            }
            num++;
            this.notifyAll();
        }
    
    
        public synchronized void del() throws InterruptedException {
            if(num==0){
                this.wait();
            }
            num--;
            this.notifyAll();
        }
    }
    

    问题存在:if 在更多线程的情况下会存在虚假唤醒问题

    if 拿到之后不会等待,while 会等待,所以当多个线程操作的时候,循环需要时候 while()

    JUC 版 生产者和消费者问题

    package pers.vincent.matrix.subject.juc;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class JucTest4 {
        public static void main(String[] args) {
            Data data = new Data();
    
            new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    data.in();
                }
            }, "A").start();
    
            new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    data.out();
                }
            }, "B").start();
    
            new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    data.in();
                }
            }, "C").start();
    
            new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    data.out();
                }
            }, "D").start();
        }
    }
    
    class Data{
    
        private int num = 0;
    
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
    
        public void in(){
    
            try {
                lock.lock();
    
                while(num!=0){
                    condition.await();
                }
                num++;
                condition.signalAll();
                System.out.println(Thread.currentThread().getName()+num);
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
    
        }
    
        public void out(){
    
            try {
                lock.lock();
    
                while(num==0){
                    condition.await();
                }
                num--;
                condition.signalAll();
                System.out.println(Thread.currentThread().getName()+num);
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
    
        }
    }
    

    Condition 的作用**: **精准的通知和唤醒线程

  • 相关阅读:
    Linux 系统下 “账户管理”
    gulp添加版本号解决缓存问题
    vue3.0的proxy浅析内层绑定原理
    rem用font-size布局与easyui的datagrid通用,出现table不显示
    堆与栈 | 对象深浅拷贝
    vue双向绑定原理值Object.defineProperty
    bootstrap模态框不出,只出现黑色蒙层bug
    Appdelegate 导航操作
    CLLocationManager 位置定位
    导航创建
  • 原文地址:https://www.cnblogs.com/blackBlog/p/13451400.html
Copyright © 2020-2023  润新知