1

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>();

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?

Thanks for the help in advance

J DOe
  • 563
  • 1
  • 8
  • 13
  • I would recommend reading this: https://stackoverflow.com/questions/36724549/a-concurrent-collection-that-maintains-insertion-order In general, if you want to use a thread safe queue with insertion order, you should use a ConcurrentLinkedQueue – Adi Ohana Apr 21 '19 at 12:11
  • We can't explain why your code behaves the way it does without seeing your code. Post your code. – JB Nizet Apr 21 '19 at 12:13

1 Answers1

0

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.

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);
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130