阻塞队列乱序 [英] Blocking Queue Take out of Order

查看:56
本文介绍了阻塞队列乱序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆