• 廖雪峰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
  • 相关阅读:
    [转载]项目风险管理七种武器之引言
    [转载]基于TFS实践敏捷-Scrum模式运用
    [转载]基于TFS实践敏捷-工作项跟踪
    [转载]TFS入门指南
    SVN — subclipse操作指引
    Java 中 方法名或类名 变更 同时 更新 所有引用的 类名或方法名 的解决方案
    Java import javax.servlet 出错
    java 中 SVN 设置所有文件及子目录 needs-lock, svn 提交时自动设置 needs-lock, 及版本不一致问题
    vmware 传输(vmdb)错误-32:pipe:read failed 解决方法
    Web.xml配置详解
  • 原文地址:https://www.cnblogs.com/csj2018/p/11013173.html
Copyright © 2020-2023  润新知