zoukankan      html  css  js  c++  java
  • condition精准控制

    Lock版的生产者消费者问题

    那么在synchronized中呢,我们是使用wait和notify来控制线程的。

    public synchronized void increment() throws InterruptedException {
           while (number != 0) {
                // 等待
                this.wait();
    
            }
            Thread.sleep(100);
            number++; // 业务
            System.out.println(Thread.currentThread().getName() + " => " + number);
            // 通知其它线程我+1加完了
            this.notifyAll();
    
        }

    用了Lock之后、会有一些细微的改变,wait->condition.await, notify->condition.signal

    class doSomething {
    
        private int number = 0;
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
    
        // +1
        public void increse() throws InterruptedException {
            lock.lock();
            try {
    
                while (number != 0) {
                    condition.await();
    
                }
                Thread.sleep(100);
                number++;
                System.out.println(Thread.currentThread().getName() + "->" + number);
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
    
                lock.unlock();
            }
    
        }
    
    
        // -1
        public void decrese() throws InterruptedException {
    
            lock.lock();
            try {
                while (number == 0) {
                    condition.await();
                }
                Thread.sleep(100);
                number--;
                System.out.println(Thread.currentThread().getName() + "->" + number);
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
        }
    
    }

    思考:既然有了wait和notify、那为什么我们还要多此一举来使用condition的等待和唤醒呢?

      这是因为condition能够做到有序,精准的通知和唤醒线程

    那么如何做到有序精准的来唤醒线程呢?

    public class C {
        public static void main(String[] args) {
            doSomething2 doSomething2 = new doSomething2();
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    doSomething2.printA();
    
                }
            }, "A").start();
    
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    doSomething2.printB();
    
                }
    
            }, "B").start();
    
            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    doSomething2.printC();
    
                }
    
            }, "C").start();
    
        }
    }
    
    @SuppressWarnings("all")
    class doSomething2 {
    
        private int number = 1;
        Lock lock = new ReentrantLock();
        private Condition condition1 = lock.newCondition();
        private Condition condition2 = lock.newCondition();
        private Condition condition3 = lock.newCondition();
    
        public void printA() {
            lock.lock();
            try {
                while (number != 1) {
                    // 等待
                    condition1.await();
                }
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + "AAA");
                // 唤醒
                condition2.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void printB() {
            lock.lock();
            try {
                while (number != 1) {
                    // 等待
                    condition2.await();
                }
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + "BBB");
                // 唤醒
                condition3.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void printC() {
            lock.lock();
            try {
                while (number != 1) {
                    // 等待
                    condition3.await();
                }
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + "CCC");
                // 唤醒
                condition1.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    }
    
    
  • 相关阅读:
    redis 批量删除key
    控制台直接执行sql语句
    item2 快捷键
    mac mamp环境 PHP命令行反应缓慢解决
    composer gitlab 搭建私包
    PostgreSql命令
    maven 程序包com.sun.image.codec.jpeg
    lumen配置日志daily模式
    PHPStorm怎么修改选中的背景颜色呢?
    vim 配置文件.vimrc,高亮+自动缩进+行号+折叠+优化
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14860873.html
Copyright © 2011-2022 走看看