Synchronization
A very interesting feature of Java objects is that they are "lockable" objects. That is the the java.lang.Object class implements an implicit locking mechanism that allows any Java object to be locked during the execution of a synchronized method or synchronized block. So that the thread that holds the lock gains exclusive access to the object for the duration of the method call or scope of the block. No other thread can "acquire" the object until the thread that holds the lock "releases" the object. This synchronization policy provides mutual exclusion.
Synchronized methods are methods that lock the object on entry and unlock the object on exit. The object class implements some special methods for allowing a thread to explicitly release the lock while in the method, wait indefinitely or for some time interval, and then try to reacquire the lock when some condition is true. Two other methods allow a thread to signal waiting thread(s) to tell them to wakeup: the notify method signals one thread wakeup and notifyAll method signals all threads to wake up and compete to try to re-acquire the lock on the object. This type of synchronized object is typically used to protect some shared resource using two types of methods.
Synchronized method
The synchronized method declaration qualifiers syntactic sugar for the fact that the entire scope of the procedure is to be governed by the mutual exclusion condition obtained by acquiring the object's lock.
Syntax
public synchronized void consume()
{
while(!consumable())
{
//release lock and wait for resource
wait();
}
//have exclusive access to resource
}
public synchronized void produce()
{
// change of state must result in consumable condition being true.
notifyAll();
//notify the all waiting threads to try consuming
}
Synchronized Block
A synchronized block allows the granularity of a lock to be finer grained than a procedure scope. The argument given to the synchronized block is a reference to an object. What about recursive locking of the same object?
Syntax
public void consume()
{
// code of consuming
}
Example: This program has a synchronized block.
class A
{
void callable(String message)
{
System.out.println(message);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
class B implements Runnable
{
String message;
A obj_A1;
Thread t;
public B(A obj_A2, String s)
{
obj_A1 = obj_A2;
message = s;
t = new Thread(this);
t.start();
}
//using synchronize block
public void run()
{
synchronized(obj_A1)
{
obj_A1.callable(message);
}
}
}
//this the main class having main method
class SynchronizedDemo
{
public static void main(String args[])
{
A obj_A1 = new A();
B b1 = new B(obj_A1, "Excution line one[1] ");
B b2 = new B(obj_A1, "Excution line two[2]");
B b3 = new B(obj_A1, "Excution line Three[3]");
// wait for threads to end
try
{
b1.t.join();
b2.t.join();
b3.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
Output
In this programm if we are not using the synchronized block then the ouput might be different: they might not execute in asynchronous order:
//without using synchronize block
public void run()
{
obj_A1.callable(message);
}
Output
Thank you......