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.
Why do you expect sequential order?
The execution could be: