It may happen that when two or more threads are running concurrently,They may require access to the same resource.Therefore there must be some mechanism to ensure that only one thread gets access to resource at a time.This is known as synchronization.
Multithreading provides asynchronous(not continuous) behavior to the programs. But wanted that two threads to communicate and share complicated data structures then there must be some provision to get synchronous behavior. One way is the "monitor (semaphore)". Monitor is an object that is used as a mutually exclusive lock or mutex. Once a thread enters a monitor all other threads must wait until that thread exits the monitor. In this way it is possible to process a data from being manipulated by more than one thread at a time. A thread can own a monitor only if no other thread owns the monitor. If the monitor is available, a thread can own the monitor and have exclusive access to the resource associated with the monitor. If the monitor is not available, the thread is suspended until the monitor becomes available. Programmers say that the thread is waiting for the monitor.
There is no class "Monitor" in Java, instead, each object has its own implicit monitor that is automatically entered when one of the object’s synchronized methods is called. Once a thread is inside a synchronized method no other thread thread can call any other synchronized method on the same object.
Synchronization can be achieved by two ways:
1. Synchronized method
2. Synchronized block
Synchronized method
Synchronization is easy in Java, because all objects have their own implicit monitor associated with them. To enter an object’s monitor, just call a method that has been modified with the synchronized keyword. While a thread is inside a synchronized method, all other threads that try to call it (or any other synchronized method) on the same instance have to wait. To exit the monitor and relinquish control of the object to the next waiting thread, the owner of the monitor simply returns from the synchronized method.
Ex, synchronized void data()
{
// code here is synchronized
}
Example
// synchronized method
class Callme
{
synchronized void call(String msg)
{
System.out.print("[" + msg);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable
{
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s)
{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
target.call(msg);
}
}
class SyncMethod
{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "Block");
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();
ob3.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
Synchronized block
Synchronizing a method is the best way to restrict the use of a method one thread at a time. However, there will be occasions when you won’t be able to synchronize a method, such as when you use a class that is provided to you by a third party. In such cases, you don’t have access to the definition of the class, which prevents you from using the synchronized keyword.
An alternative to using the synchronized keyword is to use the synchronized statement. A synchronized statement contains a synchronized block, within which is placed objects and methods that are to be synchronized. Calls to the methods contained in the synchronized block happen only after the thread enters the monitor of the object.
The general form of the synchronized statement is as follow.
synchronized(object)
{
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object’s monitor.
Although methods can be called within a synchronized block, the method declaration must be made outside a synchronized block.
Example
// Synchronized block
class Callme
{
void call(String msg)
{
System.out.print("[" + msg);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable
{
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s)
{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
synchronized(target)
{
target.call(msg);
}
}
}
class SyncBlock
{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "Block");
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();
ob3.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
Posted by :Ruchita Pandya
No comments:
Post a Comment