Java中的ConcurrentLinkedQueue使用解析
作者:小宇宙121
这篇文章主要介绍了Java中的ConcurrentLinkedQueue使用解析,一个基于链接节点的无界线程安全队列,此队列按照 FIFO(先进先出)原则对元素进行排序,队列的头部是队列中时间最长的元素,需要的朋友可以参考下
定义
一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。
队列的头部是队列中时间最长的元素。
队列的尾部是队列中时间最短的元素。 新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。
当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。
此队列不允许使用 null 元素。
函数
- offer(E e) 将指定元素插入此队列的尾部。
- poll() 获取并移除此队列的头,如果此队列为空,则返回 null
- add() 与offer(E e)完全一样,都是往队列尾部添加元素
- peek() 获取但不移除此队列的头;如果此队列为空,则返回 null
- remove(Object o) 从队列中移除指定元素的单个实例(如果存在)
- contains(Object o) 如果此队列包含指定元素,则返回 true
- toArray() 返回以恰当顺序包含此队列所有元素的数组
- toArray(T[] a) 返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型
- size() 返回此队列中的元素数量
- isEmpty 返回队列是否为空
注意:当需要判断队列是否有值时,推荐使用isEmpty(),size()的时间复杂度是o(n),当数据量很大时,会比isEmpty()消耗明显多的时间。
下面比较一下isEmpty()和size()耗时:
public class ConcurrentLinkedQueueTest {
private static final Logger logger = LoggerFactory.getLogger(ConcurrentLinkedQueueTest.class);
public static void main(String args[]) throws InterruptedException {
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
int serviceNum = 10;//服务窗口数
int perpeoNum = 10000;//买车票人数
CountDownLatch countDownLatch = new CountDownLatch(serviceNum);//初始值是线程的个数
//将买票人数放入队列
for(int i=0; i<perpeoNum; i++){
queue.add("买票人_" + i);
}
//执行10个线程从队列取出买票人
logger.info("-----开始卖票了--------");
long start = System.currentTimeMillis();
ExecutorService service = Executors.newFixedThreadPool(10);
for(int i=0; i<serviceNum; i++){
service.submit(new Windows("窗口号_" + i , queue, countDownLatch));
}
//等待所有线程都执行完,主线程再执行。
countDownLatch.await();
logger.info("-----所有人都买完票了----");
long time = System.currentTimeMillis() - start;
logger.info("总消耗时间是:{}",time);
service.shutdown();
}
private static class Windows implements Runnable{
private String name;
private ConcurrentLinkedQueue queue;
private CountDownLatch countDownLatch;
public Windows(String name, ConcurrentLinkedQueue queue, CountDownLatch countDownLatch){
this.name = name;
this.queue = queue;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
// while (!queue.isEmpty()){
while(queue.size() > 0){
logger.info(queue.poll() + "---买票完毕---{}", name );
}
countDownLatch.countDown();//线程执行完,count值-1
}
}
}执行结果: 使用size(),耗时511ms; 使用isEmpty(),耗时125ms; 所以优先使用isEmpty();
CountDownLatch
CountDownLatch是一个非常实用的多线程控制工具类,例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。
每当一个线程完成了自己的任务后,计数器的值就会减1。
当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
到此这篇关于Java中的ConcurrentLinkedQueue使用解析的文章就介绍到这了,更多相关ConcurrentLinkedQueue使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
