Java多线程之阻塞队列

Java多线程之阻塞队列

Java核心技术卷(10th)读书笔记
  1. 对于许多线程问题, 可以通过使用一个或多个队列以优雅且安全的方式将其形式化。生 产者线程向队列插人元素, 消费者线程则取出它们。使用队列,可以安全地从一个线程向另 一个线程传递数据。

  2. 当试图向队列添加元素而队列已满, 或是想从队列移出元素而队列为空的时候, 阻塞队 列(blocking queue ) 导致线程阻塞。 在协调多个线程之间的合作时,阻塞队列是一个有用的 工具。工作者线程可以周期性地将中间结果存储在阻塞队列中。其他的工作者线程移出中间 结果并进一步加以修改。队列会自动地平衡负载。如果第一个线程集运行得比第二个慢, 第 二个线程集在等待结果时会阻塞。如果第一个线程集运行得快, 它将等待第二个队列集赶上 来。

    阻塞队列的方法

    方法正常动作特殊情况下的动作
    add添加一个元素如果队列满,则抛出 IllegalStateException 异常
    element返回队列的头元素如果队列空,抛出 NoSuchElementException 异常
    offer添加一个元素并返回 true如果队列满,返回 false
    peek返回队列的头元素如果队列空, 则返回 null
    poll移出并返回队列的头元素如果队列空, 则返回 null
    put添加一个元素如果队列满, 则阻塞
    remove移出并返回头元素如果队列空, 则抛出 NoSuchElementException 异常
    take移出并返回头元素如果队列空, 则阻塞

    如果将队列当作线程管理工具来使用, 将要用到 puttake 方法。当试图向满的队列中添加或从空的队列 中移出元素时,addremoveelement操作抛出异常。当然,在一个多线程程序中, 队列会在任何时候空或满, 因此,一定要使用 offerpollpeek方法作为替代。这些方法如果不能完成任务,只是给出一个错误提示而不会抛出异常。

    pollpeek 方法返回空来指示失败。 因此,向这些队列中插入 null 值是非法的。

    还有带有超时的 offer 方法和 poll 方法的变体。

  3. java.util.concurrent 包提供了阻塞队列的几个变种。

    1. 默认情况下,LinkedBlockingQueue 的容量是没有上边界的,但是,也可以选择指定最大容量。

    2. LinkedBlockingDeque 是一个双端的版本。

    3. ArrayBlockingQueue 在构造时需要指定容量,并且有一个可选的参数来指定是否需要公平性。若设置了公平参数, 则那么等待了最长时间的线程会优先得到处理。通常,公平性会降低性能,只有在确实非常需要时才使用它。

    4. PriorityBlockingQueue 是一个带优先级的队列, 而不是先进先出队列。元素按照它们的优先级顺序被移出。该队列是没有容量上限,但是,如果队列是空的, 取元素的操作会阻塞。

    5. 最后, DelayQueue 包含实现 Delayed 接口的对象:

      interface Delayed extends Comparable { 
          long getDelay(TimeUnit unit); 
      }
      

      getDelay方法返回对象的残留延迟。负值表示延迟已经结束。元素只有在延迟用完的情 况下才能从 DelayQueue 移除。还必须实现 compareTo 方法。DelayQueue 使用该方法对元素进行排序。

    6. JavaSE 7增加了一个TransferQueue 接口,允许生产者线程等待, 直到消费者准备就绪 可以接收一个元素。如果生产者调用 q.transfer(iteni); 这个调用会阻塞, 直到另一个线程将元素( item) 删除。LinkedTransferQueue 类实现了这个接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值