java收集Java学习笔记

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

2016-12-23  本文已影响69人  专职跑龙套

竞争条件

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

竞争条件 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)

上一篇下一篇

猜你喜欢

热点阅读