“solved” it using “dummy messages” throughout. It is a bad idea? What are the possible solutions?
This is not a bad idea, it is called "Poison Pills" and is a smart way to stop a thread-based service.
But it works only when the number of manufacturers and consumers is known.
There are two threads in the code you sent: one is the "main thread" that produces the data, the other is the "processing thread" that consumes the data, "poison tablets" work well for this circumstance.
But to imagine, if you have other manufacturers, how the consumer knows when to stop (only when all manufacturers send "Poison Pills"), you need to know exactly the number of all manufacturers and check the number of "Poison Pills" with the consumer, if it is equal to the number manufacturers, which means that all manufacturers stopped working, then the consumer stopped.
In the "main thread" you need to catch an InterruptedException , because if not, the "main thread" may not be able to set a "Poison Pill". You can do this as below
... try { // do normal processing } catch (InterruptedException e) { /* fall through */ } finally { MyObject dummy = new MyObject(); dummy.setData("END"); ... } ...
Alternatively, you can try using ExecutorService to solve all problems.
(It works when you just need to do some work, and then stop when everything is complete)
void doWorks(Set<String> works, long timeout, TimeUnit unit) throws InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); try { for (final String work : works) exec.execute(new Runnable() { public void run() { ... } }); } finally { exec.shutdown(); exec.awaitTermination(timeout, unit); } }
I study and do not want to start "doing it wrong"
You may need to read the book "Java: Java Concurrency" in practice. Believe me, this is the best.