Showing posts with label thread. Show all posts
Showing posts with label thread. Show all posts

Friday, April 5, 2013

Threads signaling mechanisms in Java

In Java, there might be situations where you want to perform an operation on a certain thread and then, the same thread should wait for a certain condition before completing its task. This condition happens after another thread completes its execution.

For instance, we want to run a syncronous method on thread-1:





A first option to do this is by using the wait() and notify() methods provided by Object class.
The first thread calls wait() and the callback thread calls notify().


We must be carful though, because if the notify() method happens-before the wait() one, the waiting thread will wait forever.

To prevent this, we need a boolean variable, that can be used to prevent a similar scenario:





It is also possible to use Semaphore class, from java.util.concurrent package and call acquire() and release() methods to do the same thing.

Take a look also at this interesting tutorial that deals with many important Java concurrency topics:
http://tutorials.jenkov.com/java-concurrency/index.html

Sunday, December 23, 2012

Threading, loopers and messaging queues in Android

Android provides an efficient way to allow communication between different threads.
One thread can communicate with another by creating a Message object. Usually a Message is not created with the normal constructor; instead, it is used one of the static factory methods provided by the class, for instance obtain(Handler h, int what, Object data).

One way to send a message to another thread is to create a Messenger object and invoke the send method with the Message to send.
But how can we pass to the messenger which thread will receive the message? In the constructor, it is specified the handler bound to the target thread, i.e. the thread that will receive a messenger. An Handler is an object that, as its name suggests, when created, binds itself with the thread that is creating it.
Consequently, the receiver thread will create the handler, that will be used by the sender thread that calls the send() method with a Messenger object.

This is the basic behavior.
But usually we want that, at least the receiver thread, will be running indefinitely, or at least, as long as we need it running.
We can use a Looper object to transform a simple "one-shot" thread, in a thread that runs indefinitely, or at least, as long as the quit() method is not called, to quit the loop.
The Looper class "enriches" the behavior of a thread in two ways:

  • transforms a thread in an indefinite one
  • creates internally a messaging queue that provides a serialized handling of the messages received. A message received is handled in the handleMessage() method of Handler.Callback.
In the script above, the code between Looper.prepare() and Looper.loop() creates a handler that will handle the messages received by the current thread. If a message is received before the handler has finished processing the message, it will be automatically enqueued and executed as soon as the previous message has been completely processed.


The Handler subclass manages the incoming message. In the example above, it just prints the data received and sleeps for 2 seconds.

I have created a short demo project consisting of a main activity and a looper thread. The looper thread processes in its queue messages sent by the main thread (ui thread) of MainActivity. A message is sent each time the button send is pressed by the user. I have inserted a sleep of 2 seconds in the handler() method of the handler bound to the receiver thread, to show that if a user clicks quickly many times on the send button, the message queue handles the incoming messages sequentially, one after the other.

The demo project can be downloaded from here:
TestLooper

Pleas note that I had to use wait() and notify() methods because the code that trasforms the thread in a looper is not so immediate, so before getting the handler we must be sure that the looper has been created.