Thursday, May 29, 2014

Synchronizing a static method in java- Thread Communication - wait notify



Static methods synchronize on the class lock. Acquiring and relinquishing a class lock by a thread in order to execute a static synchronized method is analogous to that of an object lock for a synchronized instance method.

A thread acquires the class lock before it can proceed with the execution of any static synchronized method in the class, blocking other threads wishing to execute any static synchronized methods in the same class. 

This does not apply to static, non-synchronized methods, which can be invoked at any time. 
A thread acquiring the lock of a class to execute a static synchronized method has no effect on any thread acquiring the lock on any object of the class to execute a synchronized instance method.
In other words, synchronization of static methods in a class is independent from the synchronization of instance methods on objects of the class. A subclass decides whether the new definition of an inherited synchronized method will remain synchronized in the subclass.


Waiting and Notifying
Waiting and notifying provide means of communication between threads that synchronize on the same object . The threads execute wait() and notify() (or notifyAll()) methods on the shared object for this purpose. 
These final methods are defined in the Object class and, therefore, inherited by all objects. These methods can only be executed on an object whose lock the thread holds (in other words, in synchronized code), otherwise, the call will result in an IllegalMonitorStateException.

final void wait(long timeout) throws InterruptedException
final void wait(long timeout, int nanos) throws InterruptedException
final void wait() throws InterruptedException

A thread invokes the wait() method on the object whose lock it holds. The thread is added to the wait set of the current object.

final void notify()
final void notifyAll()

A thread invokes a notification method on the current object whose lock it
holds to notify thread(s) that are in the wait set of the object.
Communication between threads is facilitated by waiting and notifying, as illustrated
by Figure below.



A thread usually calls the wait() method on the object whose lock it holds because a condition for its continued execution was not met.
The thread leaves the Running state and transits to the Waiting-for notification state. There
it waits for this condition to occur. The thread relinquishes ownership of the object lock.

Transition to the Waiting-for-notification state and relinquishing the object lock are completed as one atomic (non-interruptible) operation. The releasing of the lock of the shared object by the thread allows other threads to run and execute synchronized code on the same object after acquiring its lock. Note that the waiting thread relinquishes only the lock of the object on which the
wait() method was invoked. It does not relinquish any other object locks that it might hold, which will remain locked while the thread is waiting. Each object has a wait set containing threads waiting for notification. Threads in the Waiting-for-notification state are grouped according to the object whose wait() method they invoked.


Figure above shows a thread t that first acquires a lock on the shared object, and afterward invokes the wait() method on the shared object. This relinquishes the object lock and the thread t awaits to be notified. While the thread t is waiting, another thread t can acquire the lock on the shared object for its own purposes. A thread in the Waiting-for-notification state can be awakened by the occurrence of any one of these three incidents:

1. Another thread invokes the notify() method on the object of the waiting
thread, and the waiting thread is selected as the thread to be awakened.
2. The waiting thread times out.
3. Another thread interrupts the waiting thread.

notify() does not release lock, but when  block will complete lock will be released by thread.


Why can't Java constructors be synchronized?

Because synchronized guarantees that actions on the same objects are not to be performed by multiple threads. And when the constructor is called you still don't have the object. It is logically impossible for two threads to access the constructor of the same object.






No comments:

Post a Comment