Очередь блокировки вывести из строя - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть простая очередь блокировки, содержащая целые числа. В многопоточной среде я беру и добавляю элементы в конец очереди.

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

Это неожиданное поведение? Сейчас я тестируюсь только в однопоточных средах, поэтому я ожидаю, что порядок удаления из очереди останется соответствующим добавленному порядку.

Есть ли другая потокобезопасная структура данных, которую я должен использовать вместо этого?

Заранее спасибо за помощь

1 Ответ

0 голосов
/ 21 апреля 2019

Вы должны убедиться, что взятие и печать являются атомарными операциями, без этого вы можете иметь

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);
}
...