目录
LinkedBlockingQueue源码中:
* Linked queues typically have higher throughput than array-based queues but * less predictable performance in most concurrent applications.Linked queues吞吐量比array-based queues 高但是 性能不如它,
二者区别
ArrayBlockingQueue内部使用1个锁来控制队列项的插入、取出操作,而LinkedBlockingQueue则是使用了2个锁来控制,一个名为putLock,另一个是takeLock,但是锁的本质都是ReentrantLock。
Array里面使用的时一个锁,不管put还是take行为,都可能被这个锁卡住,而Linked里面put和take是两个锁,put只会被put行为卡住,而不会被take卡住,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,因此吞吐性能自然强于Array。
Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.
吞吐量实验
下面的两段程序只有这一处不一样:
使用生产者消费者模型去测试队列的吞吐量,用一个线程池生产任务放到 任务队列中,另一个线程池从任务队列中拿到并消费任务。
生产者和消费者线程池内部的队列都是ArrayBlockingQueue,而联系生产者和消费者的任务队列一个是ArrayBlockingQueue, 一个是LinkedBlockingDeque。
BlockingQueue<Integer> DATA_QUEUE = new ArrayBlockingQueue<>(taskNum);BlockingQueue<Integer> DATA_QUEUE = new LinkedBlockingDeque<>(taskNum);
import java.util.concurrent.*;
public class AQueuethroughputTest {
public static void main(String[] args) throws InterruptedException {
int taskNum = 1000000, coreNum = 16;
BlockingQueue<Integer> DATA_QUEUE = new ArrayBlockingQueue<>(taskNum);
ThreadPoolExecutor producer = new ThreadPoolExecutor(coreNum,coreNum,
0, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(taskNum));
for (int i = 0; i < taskNum; i++) {
int finalI = i+1;
producer.execute(() -> {
DATA_QUEUE.add(finalI);
System.out.println("已添加任务,任务序列号为: "+finalI);
});
}
ThreadPoolExecutor consumer = new ThreadPoolExecutor(coreNum,coreNum,
0, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(taskNum));
CountDownLatch latch = new CountDownLatch(taskNum);
long startTime = System.currentTimeMillis();
for (int i = 0; i < taskNum; i++) {
int num = DATA_QUEUE.take();
consumer.submit(() -> {
System.out.println("==已处理任务,任务序列号是: " + num+"==");
latch.countDown();
});
}
latch.await();
System.out.println("任务执行完毕");
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
System.out.println("吞吐量tps :"+ (double)taskNum/(endTime - startTime)*1000);
}
}
import java.util.concurrent.*;
public class LQueuethroughputTest {
public static void main(String[] args) throws InterruptedException {
int taskNum = 1000000, coreNum = 16;
BlockingQueue<Integer> DATA_QUEUE = new LinkedBlockingDeque<>(taskNum);
ThreadPoolExecutor producer = new ThreadPoolExecutor(coreNum,coreNum,
0, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(taskNum));
for (int i = 0; i < taskNum; i++) {
int finalI = i+1;
producer.execute(() -> {
DATA_QUEUE.add(finalI);
System.out.println("已添加任务,任务序列号为: "+finalI);
});
}
ThreadPoolExecutor consumer = new ThreadPoolExecutor(coreNum,coreNum,
0, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(taskNum));
CountDownLatch latch = new CountDownLatch(taskNum);
long startTime = System.currentTimeMillis();
for (int i = 0; i < taskNum; i++) {
int num = DATA_QUEUE.take();
consumer.submit(() -> {
System.out.println("==已处理任务,任务序列号是: " + num+"==");
latch.countDown();
});
}
latch.await();
System.out.println("任务执行完毕");
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
System.out.println("吞吐量tps :"+ (double)taskNum/(endTime - startTime)*1000);
}
}
结果展示
ArrayBlockingQueue:
LinkedBlockingDeque:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92808.html