Synchronisation
When two or more threads needs access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time. The process by which it is achieved is called synchronisation. Java provides a language level support for it. Key to synchronisation is the concept of monitor. A monitor is an object that is used as a mutually exclusive lock. Only one thread can own a monitor at a given time.When a thread acquires a lock it’s said to have entered the monitor All other threads attempting to enter the locked monitor will be suspended until the first thread exists the monitor. These other threads are said to be waiting for the monitor. A thread that owns a monitor can re-enter the same monitor if it so desires. We can synchronise our code in two ways as follows:
I. Using Synchronised methods:
In Java all objects have their own implicit monitors associated with them. To enter an object’s monitor, we just need to call a method that has been modified with the synchronised keyword. While a thread is inside a synchronised method, all other threads that try to call it 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 to the synchronised method.synchronised type method-name(parameter list)
{
// Body of the method
}
II. Synchronised statement:
Synchronised methods will not work in all cases. Suppose we want to synchronise access to objects of a class that was not designed for multi-threaded access, i.e.- the class doesn’t use the synchronise method. Furthermore it may happen that the class wasn’t created by us but by a third party and we don’t have the access to the source code. Thus we can’t add synchronised to the appropriate method within the class, then how can access to an object of this class be synchronised? The solution is we put all the calls to the methods defined by this class inside a synchronised block.synchronised (Object-ref)
{
// Statements to be synchronised
}
This is the general form of synchronised statement. Here the Object-ref is the reference to an object being synchronised.
Inter-thread communication
The use of implicit monitors in Java objects is powerful but we can achieve a subtler level of control through inter-process communication. Multi-threading replaces event loop programming by dividing the task into discrete logical unit. Thread also provide a secondary benefit that they do away with polling. To avoid polling, Java includes an elegant inter-thread communication mechanism via the wait(), notify(), notifyAll().These methods are implemented as final method in objects, so all classes have them. All these three methods can be called only from within a synchronised context.
a) wait() :
Tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls noitify() or notifyAll().b) notify() :
Wakes up a thread that called wait() on the same object.c) notifyAll():
Wakes up all the thread that called wait() on the same object. Only one of the thread will be granted access.
class Q
{
int n;
boolean valueSet = false;
synchronized int get()
{
while(!valueSet)
try
{
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptedException
caught");
}
System.out.println("Got:
" + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n)
{
while(valueSet)
try
{
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptedException
caught");
}
this.n = n;
valueSet = true;
System.out.println("Put:
" + n);
notify();
}
}
class Producer implements
Runnable
{
Q q;
Producer(Q q)
{
this.q = q;
new Thread(this,
"Producer").start();
}
public void run()
{
int i = 0;
while(true)
{
q.put(i++);
}
}
}
class Consumer implements
Runnable
{
Q q;
Consumer(Q q)
{
this.q = q;
new Thread(this,
"Consumer").start();
}
public void run()
{
while(true)
{
q.get();
}
}
}
class PCFixed
{
public static void main(String
args[])
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press
Control-C to stop.");
}
}
No comments:
Post a Comment