首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >是否可以对有界队列使用毒丸方法?

是否可以对有界队列使用毒丸方法?
EN

Stack Overflow用户
提问于 2011-12-29 20:27:31
回答 4查看 3K关注 0票数 19

在Java Concurrency In Practice一书(第156页)中,有一条关于毒丸方法的声明:

毒丸仅适用于未绑定的队列。

这是不是意味着使用有界队列我可以得到死锁,或者这是关于一些其他的活跃性问题?它与生产商和客户的数量有关吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-29 20:29:54

使用有界队列,可以阻止您添加毒丸。

避免此问题的一种方法是在添加毒丸时使有界队列允许更多的毒丸。

票数 7
EN

Stack Overflow用户

发布于 2011-12-31 03:35:38

问题是,在关闭时,队列可能会满。

这取决于队列中的数据在关闭时的价值。你能负担得起把队列中的所有东西都扔掉吗?

当关闭队列的时候,在添加毒丸之前首先排空队列应该是有效的。

代码语言:javascript
复制
void close () throws InterruptedException {
  do {
    // Empty the queue.
    while ( queue.poll(0,TimeUnit.MILLISECONDS) != null ) {
      // Throw it away.
    }
    // Keep draining the queue 'till the pill is swallowed.
  } while (!queue.offer(STOP, 0, TimeUnit.MILLISECONDS)) ;
}

当然,如果队列中的项很有价值,您可能希望使用drainto并保留它们。

还请记住,在毒丸之后,可能会有更多的项目添加到队列中,因为不仅队列可能已满,还可能有线程被阻塞,等待发送到队列中。

票数 6
EN

Stack Overflow用户

发布于 2017-02-25 06:17:07

@gstackoverflow:有界队列的主要问题是它有一个最大容量,所以如果你的有界队列是满的,当你想要添加这个“毒丸”时,你会被阻塞。

请记住,毒丸必须立即放置,不能等到队列有一定的空间,因为此技术用于在发生异常时优雅地关闭消费者(否则会有更好的技术来关闭消费者)。

Java :作为一个例子,我们来看一个简单的例子(这个例子的所有功劳都归功于并发性),它有一个生产者线程和一个消费者线程:

代码语言:javascript
复制
public class CrawlerThread extends Thread { //The Producer Thread
  public void run() {
    try {
      crawl(root);
    } catch (InterruptedException e) { /* fall through */ }
    finally {
      while (true) {
        try {
          queue.put(POISON);
          break;
        } catch (InterruptedException e1) { /* retry */ }
      }
    }
  }
  private void crawl(File root) throws InterruptedException {
    //some code
  }
}
public class IndexerThread extends Thread { //The consumer Thread
  public void run() {
    try {
      while (true) {
        File file = queue.take();
        if (file == POISON)
        break;
        else
        indexFile(file);
      }
    } catch (InterruptedException consumed) { }
  }
}

现在,当您检查生产者线程(CrawlerThread)时,您会看到毒丸要么放在运行的末尾,要么放在一个更可怕的情况下,当出现异常时。

现在假设您想要使用一个有界队列作为生产者和消费者之间的接口,假设队列在时间t已满,并且生产者在时间t发生异常,生产者将不能将毒丸放到队列中,而不是关闭consumer线程,Consumer将仍然等待元素进入队列。因此,如果您使用有界队列,则不推荐使用毒丸方法,因为它可能会导致意外的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8667870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档