【问题标题】:Blocking Queue Take out of Order阻塞队列乱序
【发布时间】:2019-04-21 12:05:10
【问题描述】:

我有一个包含整数的简单阻塞队列。在多线程环境中,我将元素添加到队列的后面。

BlockingQueue<Integer> test = new LinkedBlockingQueue<Integer>();

目标是按顺序添加..并按相同顺序进行。在我的程序输出的第 5 行,3 以某种方式在 2 之前位于队列的前面,尽管看起来 2 是首先添加的。所有这些都是在单线程环境中添加的,所以我知道要添加的代码是按顺序执行的

 Add: 1
    Add: 2
    Add: 3
    Take: 1
    Take: 3
    Add: 4
    Take: 2
    Take: 4

这是意外行为吗?现在我只在单线程环境中进行了测试,所以我希望出队顺序与添加的顺序保持一致。

我应该使用另一个线程安全的数据结构吗?

提前感谢您的帮助

【问题讨论】:

  • 我推荐阅读这个:stackoverflow.com/questions/36724549/… 一般来说,如果你想使用带有插入顺序的线程安全队列,你应该使用 ConcurrentLinkedQueue
  • 我们无法解释为什么您的代码在没有看到您的代码的情况下会表现得如此。发布您的代码。

标签: java multithreading data-structures thread-safety blockingqueue


【解决方案1】:

你需要确保获取和打印是一个原子操作,没有这个你可以拥有

T1: take a number say 1
T2: take a number say 2
T2: print a number 2
T1: print a number 1

即除非您确保按照取值的顺序打印,否则它可以是任何顺序。

使用System.out 上的锁进行打印,因此您可以使用它来使其成为原子

synchronized (System.out) {
    Integer task = queue.take();
    // no chance of a race condition here.
    System.out.println("took " + task);
}

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2011-03-27
    • 2015-08-12
    相关资源
    最近更新 更多