In the below code, I expect the producer should produce more frequently than consumer is consuming as the producer thread priority is high. I expect to see in output that shared queue shouldn't be getting empty frequently as producer priority is high. I know jvm thread scheduling behavior is not consistent. But am I missing some concept here or does thread priority really matter to JVM?
package threading;
import java.util.LinkedList;
import java.util.Queue;
public class InterThreadCommunication {
public static void main(String args[]) {
Queue<Integer> queue = new LinkedList<Integer>();
Producer producer = new Producer(queue, 5);
producer.setPriority(Thread.MAX_PRIORITY);
Consumer consumer = new Consumer(queue, 0);
consumer.setPriority(Thread.NORM_PRIORITY);
producer.start();
consumer.start();
}
}
class Producer extends Thread {
private Queue<Integer> sharedQueue = null;
private int maxCapicity = 0;
private int prdNumber = 0;
public Producer(Queue<Integer> sharedQueue, int maxCapicity) {
this.sharedQueue = sharedQueue;
this.maxCapicity = maxCapicity;
}
public void run() {
while (true) {
synchronized (sharedQueue) {
if (sharedQueue.size() == maxCapicity) {
System.out.println("Producer : Table is full, waiting for consumers to consume");
try {
sharedQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
prdNumber++;
sharedQueue.add(prdNumber);
System.out.println("Producer produced = " + prdNumber);
sharedQueue.notify();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Consumer extends Thread {
private Queue<Integer> sharedQueue = null;
private int minCapicity = 0;
public Consumer(Queue<Integer> sharedQueue, int minCapicity) {
this.sharedQueue = sharedQueue;
this.minCapicity = minCapicity;
}
public void run() {
while (true) {
synchronized (sharedQueue) {
if (sharedQueue.size() == minCapicity) {
System.out.println("Consumer : Table is Empty, waiting for producers to produce");
try {
sharedQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int prdNumber = sharedQueue.remove();
System.out.println("Consumer consumed = " + prdNumber);
sharedQueue.notify();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
- Consumer : Table is Empty, waiting for producers to produce
Producer produced = 4
Producer produced = 5
Producer produced = 6
Producer produced = 7
Producer produced = 8
Producer : Table is full, waiting for consumers to consume
Consumer consumed = 4
Consumer consumed = 5
Consumer consumed = 6
Consumer consumed = 7
Consumer consumed = 8
Consumer : Table is Empty, waiting for producers to produce
Producer produced = 9
Producer produced = 10
Producer produced = 11
Producer produced = 12
Producer produced = 13
Producer : Table is full, waiting for consumers to consume
Consumer consumed = 9
Consumer consumed = 10
Consumer consumed = 11
Consumer consumed = 12
Consumer consumed = 13
Consumer : Table is Empty, waiting for producers to produce
Producer produced = 14
Producer produced = 15
Producer produced = 16
Producer produced = 17
Producer produced = 18
Producer : Table is full, waiting for consumers to consume
Consumer consumed = 14
Consumer consumed = 15
Producer produced = 19
Consumer consumed = 16
Producer produced = 20
Consumer consumed = 17
Consumer consumed = 18
Consumer consumed = 19
Consumer consumed = 20
Consumer : Table is Empty, waiting for producers to produce
Producer produced = 21
Producer produced = 22
Producer produced = 23
Producer produced = 24
Producer produced = 25
Producer : Table is full, waiting for consumers to consume
Consumer consumed = 21
Consumer consumed = 22
Consumer consumed = 23
Consumer consumed = 24
Consumer consumed = 25
Consumer : Table is Empty, waiting for producers to produce
After playing around with the program more and making some changes I understood that it happening because the consumer keep on acquiring the object lock till the queue is getting empty. Priority plays an important role but if threads are runnable and resources are available to acquire. I kept a loop outside the synchronization block and after notify call, the producer thread is waking up and executing in the between.
Changes in consumer class to demonstrate :
class Consumer extends Thread {
private Queue<Integer> sharedQueue = null;
private int minCapicity = 0;
public Consumer(Queue<Integer> sharedQueue, int minCapicity) {
this.sharedQueue = sharedQueue;
this.minCapicity = minCapicity;
}
public void run() {
while (true) {
synchronized (sharedQueue) {
if (sharedQueue.size() == minCapicity) {
System.out.println("Consumer : Table is Empty, waiting for producers to produce");
try {
sharedQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int prdNumber = sharedQueue.remove();
System.out.println("Consumer consumed = " + prdNumber);
sharedQueue.notify();
}
for(int i=0;i<100;i++) {
System.out.println("Consumer Thread eating time : "+i);
}
}
}
}
output :
Producer produced = 5339
Producer : Table is full, waiting for consumers to consume
Consumer consumed = 5335
Consumer Thread eating time : 0
Consumer Thread eating time : 1
Consumer Thread eating time : 2
Consumer Thread eating time : 3
Consumer Thread eating time : 4
Consumer Thread eating time : 5
Consumer Thread eating time : 6
Consumer Thread eating time : 7
Consumer Thread eating time : 8
Consumer Thread eating time : 9
Consumer Thread eating time : 10
Consumer Thread eating time : 11
Consumer Thread eating time : 12
Consumer Thread eating time : 13
Consumer Thread eating time : 14
Consumer Thread eating time : 15
Consumer Thread eating time : 16
Consumer Thread eating time : 17
Consumer Thread eating time : 18
Consumer Thread eating time : 19
Consumer Thread eating time : 20
Consumer Thread eating time : 21
Consumer Thread eating time : 22
Consumer Thread eating time : 23
Consumer Thread eating time : 24
Consumer Thread eating time : 25
Consumer Thread eating time : 26
Consumer Thread eating time : 27
Consumer Thread eating time : 28
Consumer Thread eating time : 29
Consumer Thread eating time : 30
Consumer Thread eating time : 31
Consumer Thread eating time : 32
Consumer Thread eating time : 33
Consumer Thread eating time : 34
Consumer Thread eating time : 35
Consumer Thread eating time : 36
Consumer Thread eating time : 37
Consumer Thread eating time : 38
Consumer Thread eating time : 39
Consumer Thread eating time : 40
Consumer Thread eating time : 41
Consumer Thread eating time : 42
Consumer Thread eating time : 43
Consumer Thread eating time : 44
Consumer Thread eating time : 45
Consumer Thread eating time : 46
Consumer Thread eating time : 47
Consumer Thread eating time : 48
Consumer Thread eating time : 49
Consumer Thread eating time : 50
Consumer Thread eating time : 51
Consumer Thread eating time : 52
Consumer Thread eating time : 53
Producer produced = 5340
Producer : Table is full, waiting for consumers to consume
Consumer Thread eating time : 54
Consumer Thread eating time : 55
Consumer Thread eating time : 56
Consumer Thread eating time : 57
Consumer Thread eating time : 58
Consumer Thread eating time : 59
Consumer Thread eating time : 60
Consumer Thread eating time : 61
Consumer Thread eating time : 62
Consumer Thread eating time : 63
Consumer Thread eating time : 64
Consumer Thread eating time : 65
Consumer Thread eating time : 66
Consumer Thread eating time : 67
Consumer Thread eating time : 68
Consumer Thread eating time : 69
Consumer Thread eating time : 70
Consumer Thread eating time : 71
Consumer Thread eating time : 72
Consumer Thread eating time : 73
Consumer Thread eating time : 74
Consumer Thread eating time : 75
Consumer Thread eating time : 76
Consumer Thread eating time : 77
Consumer Thread eating time : 78
Consumer Thread eating time : 79
Consumer Thread eating time : 80
Consumer Thread eating time : 81
Consumer Thread eating time : 82
Consumer Thread eating time : 83
Consumer Thread eating time : 84
Consumer Thread eating time : 85
Consumer Thread eating time : 86
Consumer Thread eating time : 87
Consumer Thread eating time : 88
Consumer Thread eating time : 89
Consumer Thread eating time : 90
Consumer Thread eating time : 91
Consumer Thread eating time : 92
Consumer Thread eating time : 93
Consumer Thread eating time : 94
Consumer Thread eating time : 95
Consumer Thread eating time : 96
Consumer Thread eating time : 97
Consumer Thread eating time : 98
Consumer Thread eating time : 99
Consumer consumed = 5336
Consumer Thread eating time : 0
Consumer Thread eating time : 1
Consumer Thread eating time : 2
Consumer Thread eating time : 3
Consumer Thread eating time : 4
Consumer Thread eating time : 5
Consumer Thread eating time : 6
Producer produced = 5341
Consumer Thread eating time : 7
Consumer Thread eating time : 8
Consumer Thread eating time : 9
Consumer Thread eating time : 10