• 锁框架:条件


    Condition声明了下列方法:

    void await(): 在接收到信号或者被中断之前,强制调用线程一直等待。

    long awaitNanos(long nanosTimeout): 在接收到信号,被中断,或者超过指定的等待时间之前,强制当前线程一直等待。

    boolean awaitUninterruptibly(): 在接收到信号之前,强制当前线程一直等待。

    void signal(): 唤醒一个等待中的线程。

    void singalAll(): 唤醒所有等待中的线程。

    示例:

    package com.lock;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * condition 条件
     *     接口condition把object的wait和notification方法(wait(),notify()和notifyAll())
     * 分解到不同的条件对象中。通过把这些条件和任意的lock实现使用组合,起到让每个对象上具有多重等待集合的作用。
     * 生产者与消费者模型
     *     用lock和condition替代synchronize和等待及通知
     *     生产一个字母后消费一个字母
     * @author Administrator
     *
     */
    public class PC {
        public static void main(String[] args) {
            Shared s = new Shared();
            new Producer(s).start();
            new Consumer(s).start();
        }
    }
    
    class Shared {
        private char c;
    
        private volatile boolean available;
    
        private final Lock lock;
    
        private final Condition condition;
    
        Shared() {
            available = false;  //初始化false,保证先生产再消费
            lock = new ReentrantLock();
            condition = lock.newCondition();  //获取特定lock实例的condition实例
        }
    
        Lock getLock() {
            return lock;
        }
    
        char getSharedChar() {
            lock.lock();
            try {
                while (!available){
                    try {
                        condition.await();
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
                available = false;
                condition.signal();
            } finally {
                lock.unlock();
                return c;
            }
        }
    
        void setSharedChar(char c) {
            lock.lock();
            try {
                while (available)
                    try {
                        condition.await();
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                this.c = c;
                available = true;  //生产一个后,必须先消费
                condition.signal();  //唤醒一个等待中的线程
            } finally {
                lock.unlock();
            }
        }
    }
    
    //生产者
    class Producer extends Thread {
        private final Lock l;
    
        private final Shared s;
    
        Producer(Shared s) {
            this.s = s;
            l = s.getLock();
        }
    
        @Override
        public void run() {
            for (char ch = 'A'; ch <= 'Z'; ch++) {
                l.lock();
                s.setSharedChar(ch);
                System.out.println(ch + " produced by producer.");
                l.unlock();
            }
        }
    }
    
    //消费者
    class Consumer extends Thread {
        private final Lock l;
    
        private final Shared s;
    
        Consumer(Shared s) {
            this.s = s;
            l = s.getLock();
        }
    
        @Override
        public void run() {
            char ch;
            do {
                l.lock();
                ch = s.getSharedChar();
                System.out.println(ch + " consumed by consumer.");
                l.unlock();
            } while (ch != 'Z');
        }
    }

     传统方式实现以上代码:通过synchronize和等待及通知实现

    package com.lock;
    
    /**
     * 生产者消费者模式
     *     生产一个字母后消费一个字母
     * @author Administrator
     *
     */
    public class PC2 {
        public static void main(String[] args) {
            Shared2 s = new Shared2();
            new Producer2(s).start();
            new Consumer2(s).start();
        }
    }
    
    class Shared2 {
        private char c;
        private volatile boolean writeable = true;
    
        synchronized void setSharedChar(char c) {
            while (!writeable)
                try {
                    wait();
                } catch (InterruptedException ie) {
                }
            this.c = c;
            writeable = false;
            notify();
        }
    
        synchronized char getSharedChar() {
            while (writeable)
                try {
                    wait();
                } catch (InterruptedException ie) {
                }
            writeable = true;
            notify();
            return c;
        }
    }
    
    class Producer2 extends Thread {
        private final Shared2 s;
    
        Producer2(Shared2 s) {
            this.s = s;
        }
    
        @Override
        public void run() {
            for (char ch = 'A'; ch <= 'Z'; ch++) {
                synchronized (s) {
                    s.setSharedChar(ch);
                    System.out.println(ch + " produced by producer.");
                }
            }
        }
    }
    
    class Consumer2 extends Thread {
        private final Shared2 s;
    
        Consumer2(Shared2 s) {
            this.s = s;
        }
    
        @Override
        public void run() {
            char ch;
            do {
                synchronized (s) {
                    ch = s.getSharedChar();
                    System.out.println(ch + " consumed by consumer.");
                }
            } while (ch != 'Z');
        }
    }
  • 相关阅读:
    解决:ElasticSearch ClusterBlockException[blocked by: [FORBIDDEN/12/index readonly / allow delete (api)];
    Centos 常用命令
    Nodejs的path模块
    webpack externals
    F#反射获取名称的三种方法
    JDK源码阅读之:JDK8的 CHM 为何放弃分段锁
    Mysql基础之:MySQL各种类型索引的及其优缺点介绍
    Java高并发之:从浅入深掌握并发执行框架Executor
    如何读懂火焰图?+ 实例讲解程序性能优化
    Java高并发之:深入浅出线程池+高级选项的使用
  • 原文地址:https://www.cnblogs.com/x-jingxin/p/10678489.html
Copyright © 2020-2023  润新知