内容简介:多个条件队列以实现更好的并发性。每个锁使用单独的条件队列的优点。以下是在无界队列之上的有界BlockingQueue的两个经典实现。
多个条件队列以实现更好的并发性。每个锁使用单独的条件队列的优点。
- 它避免了虚假的唤醒和上下文切换。例如,如果您使用notifyAll进行传统等待,则最终会唤醒正在等待不同条件的线程。
- 当您在单独的条件队列上等待时,您可以使用signal 而不是signalAll来进一步提高性能。
以下是在无界队列之上的有界BlockingQueue的两个经典实现。
每个锁具有单独的等待集
<b>public</b> <b>class</b> BlockingQueue<T> {
<b>private</b> <b>final</b> Queue<T> queue;
<b>private</b> <b>final</b> Lock lockObj = <b>new</b> ReentrantLock();
<b>private</b> <b>final</b> Condition empty = lockObj.newCondition();
<b>private</b> <b>final</b> Condition full = lockObj.newCondition();
<b>private</b> <b>int</b> maxLength;
<b>private</b> <b>int</b> currentSize = 0;
<b>public</b> BlockingQueue(<b>int</b> maxLength) {
<b>this</b>.queue = <b>new</b> ArrayDeque<T>();
<b>this</b>.maxLength = maxLength;
}
<b>public</b> <b>void</b> offer(T elem) throws InterruptedException {
lockObj.lock();
<b>try</b> {
<b>while</b> (currentSize == maxLength) {
full.await();
}
queue.offer(elem);
currentSize++;
empty.signal();
} <b>finally</b> {
lockObj.unlock();
}
}
<b>public</b> T poll() throws InterruptedException {
lockObj.lock();
<b>try</b> {
<b>while</b> (currentSize == 0) {
empty.await();
}
T elem = queue.poll();
currentSize--;
full.signal();
<b>return</b> elem;
} <b>finally</b> {
lockObj.unlock();
}
}
}
使用JMH测试吞吐量:
Benchmark Mode Cnt Score Error Units BenchmarkBlockingDequeu.testProduceAndConsume thrpt 25 12500542.933 ± 374127.076 ops/s
旧的方式(单锁和等待)
<b>public</b> <b>class</b> BlockingQueueWait<T> {
<b>private</b> <b>final</b> Queue<T> queue;
<b>private</b> <b>final</b> Object lockObj = <b>new</b> Object();
<b>private</b> <b>int</b> maxLength;
<b>private</b> <b>int</b> currentSize = 0;
<b>public</b> BlockingQueueWait(<b>int</b> maxLength) {
<b>this</b>.queue = <b>new</b> ArrayDeque<T>();
<b>this</b>.maxLength = maxLength;
}
<b>public</b> <b>void</b> offer(T elem) throws InterruptedException {
<b>synchronized</b> (lockObj) {
<b>while</b> (currentSize == maxLength) {
lockObj.wait();
}
queue.offer(elem);
currentSize++;
lockObj.notifyAll();
}
}
<b>public</b> T poll() throws InterruptedException {
<b>synchronized</b> (lockObj) {
<b>while</b> (currentSize == 0) {
lockObj.wait();
}
T elem = queue.poll();
currentSize--;
lockObj.notifyAll();
<b>return</b> elem;
}
}
}
使用JMH测试吞吐量:
Benchmark Mode Cnt Score Error Units BenchMarkBlockingWait.testProduceAndConsume thrpt 25 2702842.067 ± 24534.073 ops/s
如果你仔细看看上面的实现,ops /s的差异是巨大的,其中大部分是由虚假的唤醒引起的,并且没有使用显式条件队列和每个锁的等待集,你最终会浪费宝贵的cpu周期。因此,如果您正在编写并发库实现,请记住您有更好的并发支持,并且您可以为每个锁创建多个条件队列以避免虚假唤醒。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Redis 5.0 Stream消息队列会每次唤醒所有同一个group内的消费者
- 语音唤醒实现
- RunLoop的唤醒探索
- H5唤醒App之scheme方案
- 每日一博 | java 通过网络唤醒实现远程开机
- rabbitmq实现延时队列(死信队列)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Tensorflow:实战Google深度学习框架
郑泽宇、顾思宇 / 电子工业出版社 / 2017-2-10 / 79
TensorFlow是谷歌2015年开源的主流深度学习框架,目前已在谷歌、优步(Uber)、京东、小米等科技公司广泛应用。《Tensorflow实战》为使用TensorFlow深度学习框架的入门参考书,旨在帮助读者以最快、最有效的方式上手TensorFlow和深度学习。书中省略了深度学习繁琐的数学模型推导,从实际应用问题出发,通过具体的TensorFlow样例程序介绍如何使用深度学习解决这些问题。......一起来看看 《Tensorflow:实战Google深度学习框架》 这本书的介绍吧!