I'm making a project with 5 packages. The packages can communicate with each other by sending Messages to a central MessageQueue in the Main package and that MessageQueue takes care of all the messages. (cfr.: http://en.wikipedia.org/wiki/Java_Message_Service)
Provided this image:
the packages would be the clients (both publisher and subscriber) and the MessageQueue would be the topic.
I'm now implementing the MessageQueue (a.k.a. the Topic in the image above) and packages can already subscribe to Messages and packages can also publish a Message.
Publishing a Message is just adding the Message to a queue 'inside' the MessageQueue.
So at a given time during execution there can be 0, 1 or more messages in the MessageQueue and now i must make sure the MessageQueue processes all these messages correctly (and in order).
A way of doing this could look like this:
public class MessageQueue {
public MessageQueue(){
//initialising etc.
processMessages();
}
private void processMessages(){
while(/*program is running*/){
if(queue.isNotEmpty()){
/*process first message in queue*/
}
}
}
However, i believe this is not a great design and is sometimes referred to as busy waiting?
How could i approach this in a better way (without using any standard APIs ofcourse)?
Best Answer
As you said, you are doing a busy waiting, here. You need to make your thread block until the message queue becomes non-empty.
The primitives for doing that are the methods
wait
andnotify
of classObject
. Using correctly these primitives can be tricky, even when you have a good understanding of multithreading. Basically,wait
makes a thread block, andnotify
sends a signal to the waiting thread.A more high-level tool (which are certainly built on top of
wait
andnotify
) are the classes from the packagejava.util.concurrent.locks
. Mainly,Lock
andCondition
. ACondition
have similar methods thanwait
andnotify
.Another tool you can use is a
BlockingQueue
. When asked to give an object, a blocking queue will block the current thread until it becomes non-empty. Under the hood, it uses the same wait/notify primitives described above. It's a valid solution for your specific problem.A higher level solution, which abstracts you from the executing thread, is to use an
ExecutorService
.ExecutorService.newSingleThreadExecutor()
would do the trick. Just submitRunnable
objects to anExecutorService
, and it will run them asynchronously in a dedicated thread.You can choose any of these solutions to implement your messaging system. It only depends on how much control you want, or what level you are trying to master (if you do this to learn programming).