阻塞队列乱序 [英] Blocking Queue Take out of Order
问题描述
我有一个包含整数的简单阻塞队列.在多线程环境中,我正在将元素添加到队列的后面并将其添加到队列的后面.
I have a simple blocking queue containing Integers. In a multi thread environment I am taking and adding elements to the the back of the queue.
BlockingQueue<Integer> test = new LinkedBlockingQueue<Integer>();
目标是按顺序进行添加,并按相同的顺序进行.在我的程序输出的第5行上,尽管3似乎先添加了2,但3在2之前一直处于队列的最前面.所有这些都是在单线程环境中添加的,所以我知道要添加的代码是按顺序执行的
The goal is to have adding in order.. and taking be in the same order as well. On the 5th line of my program output, 3 is somehow at the front of the queue before 2 is, despite it appearing that 2 was added first. All of these were added in a single threaded environment, so I know the code to be added is executed in order
Add: 1
Add: 2
Add: 3
Take: 1
Take: 3
Add: 4
Take: 2
Take: 4
这是意外行为吗?现在,我仅在单线程环境中进行过测试,因此我希望出队顺序与添加的顺序保持一致.
Is this unexpected behavior? Right now I am only tested in Single Threaded environments so I would expect the de-queing order to stay consistend with the order that was added.
是否应该使用另一个线程安全的数据结构?
Is there another thread safe datastructure that I should be using instead?
非常感谢您的帮助
推荐答案
您需要确保取纸和打印是一个原子操作,而没有这个
You need to ensure taking and printing is an atomic operation without this you can have
T1: take a number say 1
T2: take a number say 2
T2: print a number 2
T1: print a number 1
即除非您确定打印顺序与取值顺序相同,否则打印顺序可以为任意顺序.
i.e. unless you ensure printing is in the order you take the values, it can be in any order.
使用 System.out
上的锁进行打印,因此您可以使用它来使其原子化
Printing using a lock on System.out
so you can use this to make it atomic
synchronized (System.out) {
Integer task = queue.take();
// no chance of a race condition here.
System.out.println("took " + task);
}
这篇关于阻塞队列乱序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!