javamultithreadingconcurrency

Unexpected behavior with 2 enqueuing threads when using built-in java ArrayBlockingQueue and custom implementation


Unexpected behavior with 2 enqueuer threads when using built-in java ArrayBlockingQueue and custom implementation

The behavior is that I expected is that each threads enqueues and deques in the sequential order that the threads used in enqueue the values, but this is not the case.

This is the code:

public class MultiThreadTests {
  private static final int QUEUE_LENGTH = 100_000;

  public static void main(String[] args) throws InterruptedException {
    usingTwoThreadsAndArrayBlockingQueue();

  }

  private static void usingTwoThreadsAndArrayBlockingQueue() throws InterruptedException {
    ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<Integer>(QUEUE_LENGTH);

    ArrayBlockingQueueClientThread t1 = new ArrayBlockingQueueClientThread(q, 1);
    ArrayBlockingQueueClientThread t2 = new ArrayBlockingQueueClientThread(q, 2000);

    t1.start();
    t2.start();

  }

  static class ArrayBlockingQueueClientThread extends Thread {
    ArrayBlockingQueue q;
    int m;

    ArrayBlockingQueueClientThread(ArrayBlockingQueue ephemeralQueue, int m) {
      this.q = ephemeralQueue;
      this.m = m;
    }

    public void run() {
      for (int i = 0; i < 20 ; i++) {
          q.add(i * m);
      }

      // I should still see the correct order when I dequeue concurrently, but I do not.
      int k = 0;
      while(k<20)
      {
        k++;
        try {
          System.out.println(q.poll(500, TimeUnit.MILLISECONDS));
        } catch (InterruptedException e) {
          throw new RuntimeException(e);
        }
      }
    }
  }
}

This is the output (it is not consistent however): | | | ----- | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 0 | | 11 | | 12 | | 13 | | 10 | | 14 | | 16 | | 17 | | 18 | | 19 | | 0 | | 2000 | | 4000 | | 15 | | 8000 | | 10000 | | 12000 | | 14000 | | 16000 | | 18000 | | 6000 | | 22000 | | 24000 | | 26000 | | 28000 | | 30000 | | 20000 | | 34000 | | 36000 | | 32000 | | 38000 |

Some values are out of order at the thread level, such as value 15 and the value 6000. and I do not understand why this is the case. Any help is greatly appreciated.


Solution

  • Why do you expect sequential order?

    The execution could be: