Reputation: 1192
I'm working on the multiple producer and consumer use case of Producer-Consumer problem with Java. The code is on github. The same implementation worked for the single producer consumer use case, but behaved weirdly for the multiple producer consumer case.
I have some questions regarding the output:
At the start, all producers and one consumer has the lock:
Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
After it runs for a while, another weird phenomenon appears:
Producer t5 has lock
t5 produced 10, integerQueue: [8, 9, 10]
Producer t5 notifiedAll
Producer t5 has lock
t5 produced 11, integerQueue: [8, 9, 10, 11]
Producer t5 notifiedAll
Consumer t8 has lock
t8 consumed 8, integerQueue: [9, 10, 11]
Consumer t8 notified All
Consumer t8 has lock
t8 consumed 9, integerQueue: [10, 11]
Consumer t8 notified All
Any help is greatly appreciated.
Upvotes: 0
Views: 268
Reputation: 262534
You are using a single instance of your Producer5
runnable and submit it many times to the execution service.
Producer5 producer = new Producer5(queue, maxCapacity);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
So your threadName
field in that single Producer5
instance will get overwritten several times and is not useful (it will no longer print out the name of the thread that is actually running, furthermore it would need to be volatile
in order to be updated properly by multiple threads -- for some definition of properly).
System.out.println(String.format("\nProducer %s has lock",
threadName // this will be the name of the last thread that entered `run`,
// they all share the same instance
));
Do not re-use the same Runnable
instance if it contains mutable state. Make a separate instance for each thread of execution.
How did consumer thread t5 get the lock while producer thread t1 was holding it?
It was still Thread t1 running this code, but the threadName
field has in the mean-time been updated by Thread t5. Highly misleading output.
It seems all threads except one producer and consumer had died and those 2 are switching lock between each other.
The threads are all still alive, but there are only two threadName
fields in existence, that the threads have been taking turns to update (at the top of the run
method), finally settling on some value. All threads just print that value now.
Upvotes: 1