JAVA: The Synchronized Block

JAVA: The Synchronized Block

Consider an example, people standing in queue outside a telephone booth, wishing to make a call and waiting for their turn would be similar to a synchronised way of accessing data. However, if there was no queue and people were permitted to go in randomly, two or more persons would try to enter the booth at the same time resulting in confusion and chaos. This first instance is similar to the concept of synchronisation and the second, the concept of race
condition.

In general, race conditions in a program are possible when

• Two or more threads share data
• They are reading and writing the shared data simultaneously

Using the synchronized Block

It is not always possible to achieve synchronization by creating synchronized methods within classes. The reason for this is explained next.

Consider a case where the programmer wants to synchronize access to objects of a class, which does not use synchronized methods. It is also assumed that the source code is unavailable because either a third party created it or the class was imported from the built-in library. In such a case, the keyword synchronized cannot be added to the appropriate methods within the class.

Therefore, the problem here would be how to make the access to an object of this class synchronized. This can be achieved by putting all the calls to the methods defined by this class inside a synchronized block.

The general form of the synchronized statement is:

synchronized(object)

{

//statements to be synchronized

}

The reference to the object being synchronized is denoted as object. If a single statement is to be synchronized, then the curly braces are not required. A synchronized block ensures that a method can be invoked only after the current
thread has successfully entered object’s monitor. The code in the following example shows how to use the synchronized statement.

// Example for Synchronized Block

class DemoOne

{
void display(int num)
{

System.out.print(""+num);
try
{
Thread.sleep(1000);
}

catch(InterruptedException e)
{
System.out.println("Interrupted");
}

System.out.println("done");
}

}

class DemoTwo implements Runnable
{
int number;
DemoOne objOne;
Thread objTh;
public DemoTwo(DemoOne one_num, int num)
{
objOne = one_num;
number = num;
objTh = new Thread(this);
objTh.start();
}

public void run()
{
synchronized(objOne)
{
objOne.display(number);

}

}

}

class SynchBlock
{
public static void main(String args[])
{
DemoOne objOne = new DemoOne();
int digit = 10;
DemoTwo objSynch1 = new DemoTwo(objOne, digit++);
DemoTwo objSynch2 = new DemoTwo(objOne, digit++);
DemoTwo objSynch3 = new DemoTwo(objOne, digit++);

try
{
objSynch1.objTh.join();
objSynch2.objTh.join();
objSynch3.objTh.join();
}

catch(InterruptedException e)
{

System.out.println("Interrupted");
}

}

}

 

The output of the following program is: