zoukankan      html  css  js  c++  java
  • 廖雪峰Java11多线程编程-3高级concurrent包-3Condition

    1.Condition实现等待和唤醒线程

    java.util.locks.ReentrantLock用于替代synchronized加锁

    但是synchronized可以使用wait和notify实现线程在条件不满足时的等待,条件满足时的唤醒。
    如何使用ReentrantLock实现wait/notify的功能?
    这个时候我们可以使用Condition对象来实现条件不满足时的等待,条件满足时的唤醒。

    class TaskQueue{
        final Lock lock = new ReentrantLock()
        final Condition notEmpty = lock.newCondition();
    }
    

    1.1 对Condition对象调用await()方法就相当于对所对象调用wait()方法。

    ### 1.2 对Condition对象调用signalAll()就相当于在synchronized加锁对象调用notifyAll()方法。 Condition.await/signal/signalAll原理和wait/notify/notifyAll一致 * await()会释放当前锁,进入等待状态 * signal()会唤醒某个等待线程 * signalAll()会唤醒所有等待线程 * 唤醒线程从await()返回后需要重新获得锁

    2. 示例

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class TaskQueue{
        final Queue<String> queue = new LinkedList<>();
        final Lock lock = new ReentrantLock();
        final Condition notEmpty = lock.newCondition();
        public String getTask() throws InterruptedException{
            lock.lock();
            try{
                while(this.queue.isEmpty()){
                    notEmpty.await();
                }
                return queue.remove();
            }finally {
                lock.unlock();
            }
        }
        public void addTask(String name){
            lock.lock();
            try{
                this.queue.add(name);
                notEmpty.signalAll();
            }finally {
                lock.unlock();
            }
        }
    }
    class WorkerThread extends Thread{
        TaskQueue taskQueue;
        public WorkerThread(TaskQueue taskQueue){
            this.taskQueue = taskQueue;
        }
        public void run(){
            while(!isInterrupted()){
                String name;
                try{
                    name = taskQueue.getTask();
                }catch (InterruptedException e){
                    break;
                }
                String result = "Hello, "+name+" !";
                System.out.println(result);
            }
        }
    }
    public class Main{
        public static void main(String[] args) throws InterruptedException{
            TaskQueue taskQueue = new TaskQueue();
            WorkerThread worker = new WorkerThread(taskQueue);
            worker.start();
            taskQueue.addTask("Bob");
            Thread.sleep(1000);
            taskQueue.addTask("Alice");
            Thread.sleep(1000);
            taskQueue.addTask("Tim");
            Thread.sleep(1000);
            worker.interrupt();
            worker.join();
            System.out.println("END");
        }
    }
    
    ## 3. 总结 使用ReentrantLock+Condition可以更安全的实现线程的同步、等待和唤醒。 * Condition可以替代wait/notify * Condition对象必须从ReentrantLock对象获取 * ReentrantLock+Condition可以替代synchronized+wait/notify
  • 相关阅读:
    关于树及其各种操作
    正交矩阵与齐次矩阵
    矩阵的行列式与矩阵的逆
    线性变换
    矩阵
    向量的运算
    求两直线的交点
    微任务防抖
    二项分布
    二项式定理
  • 原文地址:https://www.cnblogs.com/csj2018/p/11013173.html
Copyright © 2011-2022 走看看