线程池都有哪几种工做队列

http://www.javashuo.com/article/p-mfnluzjn-ca.htmlhtml

一、ArrayBlockingQueue
是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。数组

  • ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,
    • 由此也意味着二者没法真正并行运行
    • 这点尤为不一样于LinkedBlockingQueue

二、LinkedBlockingQueue
一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量一般要高于ArrayBlockingQueue。线程

  • 静态工厂方法Executors.newFixedThreadPool()使用了这个队列

三、SynchronousQueue
一个不存储元素的阻塞队列htm

  • 每一个插入操做必须等到另外一个线程调用移除操做,不然插入操做一直处于阻塞状态,
  • 吞吐量一般要高于LinkedBlockingQueue,
  • 静态工厂方法Executors.newCachedThreadPool(5)使用了这个队列。

四、PriorityBlockingQueue对象

  • 一个具备优先级的无限阻塞队列
  • PriorityBlockingQueue也是基于最小二叉堆实现
    • 数组实现的最小堆
    • 使用基于CAS实现的自旋锁来控制队列的动态扩容,
    • 保证了扩容操做不会阻塞take操做的执行
      • 不扩容就是正常的获取锁以后加入元素
      • PriorityBlockingQueue扩容时,
        • 由于增长堆数组的长度并不影响队列中元素的出队操做,
        • 于是使用自旋CAS操做实现的锁来控制扩容操做,
        • 仅在数组引用替换拷贝元素时才加锁,
        • 从而减小了扩容对出队操做的影响

DelayQueueblog

  • 只有当其指定的延迟时间到了,才可以从队列中获取到该元素。
  • DelayQueue是一个没有大小限制的队列,
  • 所以往队列中插入数据的操做(生产者)永远不会被阻塞,而只有获取数据的操做(消费者)才会被阻塞。
  • 使用场景:
    • elayQueue使用场景较少,但都至关巧妙,
    • 常见的例子好比使用一个DelayQueue来管理一个超时未响应的链接队列。
相关文章
相关标签/搜索