美文网首页java收集Java学习笔记
Java 通过 Lock 和 竞争条件 Condition 实现

Java 通过 Lock 和 竞争条件 Condition 实现

作者: 专职跑龙套 | 来源:发表于2016-12-23 16:42 被阅读69次

    竞争条件

    多个线程共享对某些变量的访问,其最后结果取决于哪个线程偶然在竞争中获胜。

    • condition.await():类似于 obj.wait()
    • condition.signal():类似于 obj.notify()
    • condition.signalAll():类似于 obj.notifyAll()

    竞争条件 Condition 对比 obj.wait() obj.notify() 的优势

    可以建立不同的多个 Condition,针对不同的竞争条件,例如:

    Condition isFullCondition = lock.newCondition();
    Condition isEmptyCondition = lock.newCondition();
    

    关于 通过 wait 和 notify 实现生产者消费者模式,可以参考 链接

    利用 Lock 和 竞争条件 Condition 也可以实现生产者消费者模式,代码如下:

    public class Condition_Test {
        private static final int MAX_CAPACITY = 10;
        private static List<Object> goods = new ArrayList<Object>();
    
        private static final Lock lock = new ReentrantLock();
        private static final Condition isFullCondition = lock.newCondition();
        private static final Condition isEmptyCondition = lock.newCondition();
    
    
        public static void main(String[] args) {
            (new ProducerThread()).start();
    
            (new ConsumerThread()).start();
        }
    
        static class ProducerThread extends Thread {
            public void run() {
                while (true) {
                    // 每隔 1000 毫秒生产一个商品
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
    
                    // 获得锁,相当于 synchronized
                    lock.lock();
    
                    // 当前商品满了,生产者等待
                    if (goods.size() == MAX_CAPACITY) {
                        try {
                            System.out.println("Goods full, waiting...");
                            isEmptyCondition.await();
                        } catch (Exception e) {
                        }
                    }
    
                    goods.add(new Object());
                    System.out.println("Produce goods, total: " + goods.size());
    
                    // isFullCondition.signal() 也可以
                    isFullCondition.signalAll();
    
                    // 记住要释放锁
                    lock.unlock();
                }
            }
        }
    
        static class ConsumerThread extends Thread {
            public void run() {
                while (true) {
                    // 每隔 500 毫秒消费一个商品
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }
    
                    // 获得锁,相当于 synchronized
                    lock.lock();
    
                    // 当前商品空了,消费者等待
                    if (goods.size() == 0) {
                        try {
                            System.out.println("No goods, waiting...");
                            isFullCondition.await();
                        } catch (Exception e) {
                        }
                    }
    
                    goods.remove(0);
                    System.out.println("Consume goods, total: " + goods.size());
    
                    // isEmptyCondition.signal() 也可以
                    isEmptyCondition.signalAll();
    
                    // 记住要释放锁
                    lock.unlock();
                }
            }
        }
    }
    

    Condition 的实现原理

    Condition 的内部实现是使用节点链来实现的,每个条件实例对应一个节点链,我们有 isFullConditionisEmptyCondition 两个条件实例,所以会有两个等待节点链。当对应条件被 signal 的时候,就会把等待节点转移到同步队列中,继续竞争锁。


    引用:
    java并发等待条件的实现原理(Condition)

    相关文章

      网友评论

        本文标题:Java 通过 Lock 和 竞争条件 Condition 实现

        本文链接:https://www.haomeiwen.com/subject/qvkhvttx.html