(5) Threads Synchronization

Synchronization is basically connected with aquiring the lock,but what is this lock?
Every object in java has its own one and only one lock.So acquiring the lock means,one thread's getting that object's lock letting other threads to wait till it releases it.
Only methods and code blocks can have synchronized option and not variables or classes. 
When a thread goes to sleep,it does not release its locks.
A thread can acquire more than one lock. 
Anyway, synchronization slows down the process as threads have to wait to grab the lock.
Now look at this Q
  • Q)
public class ExceptionEg implements Runnable{
public synchronized void run() {
    System.out.print("A");
    System.out.print("B");
}   
    public static void main(String[] args) {
    ExceptionEg r=new ExceptionEg();
    new Thread(r).start();
    new Thread(r).start();
       
    }
}


 What would be the output?
- We know that a thread can be started only once. Before going to synchronization,you should note that .start() method is called twice.Would that be an issue?
No,because you need to see that it's not the same thread started twice,but two different threads created from the same runnable which is perfectly legal.

-Now from the synchronization aspect,you see that method run() has been synchronized,which means that a thread to execute run() it should first grab the object's lock.

Fine,now how many locks are available? To know that we need to know how many objects are there? You can see there's only one runnable object named 'r' ,start() method is called to the same runnable object 'r' through two different thread objects.So one lock.




For thread one or thread two to execute run() code it should grab that red lock shown in the picture.And once it has got that it won't release that lock until the thread dies.So 'AB' would definitely printed continuously. Thread one or thread two may grab the lock first,but it won't impact the output.
So the output is: ABAB

  
Q)
 
public class TestSeven extends Thread {
     private static int x;
     public synchronized void doThings() {
         int current = x;
         current++;
         x = current;
     }
     public void run() {
         doThings();
    }
 }


Which statement is true?
A. Compilation fails.
B. An exception is thrown at runtime.
C. Synchronizing the run() method would make the class thread-safe.
D. The data in variable "x" are protected from concurrent access problems.
E. Declaring the doThings() method as static would make the class thread-safe.


What we feel first is since method doThings() is already synchornized,class should be thread safe. But it is not :D

That is because the int x is an static variable. By synchronizing an instance method a static variable cannot be made thread safe.

To explain this clearly let's use this diagram.


 

This how x can be accessed by multiple threads resulting unexpected behaviours.

So how can make x thread safe? A good question.
There are two ways to do it.

1)By declaring the method as static as well.
2)public void doThings(){
             synchronized (TestSeven.class){
                         .
                         .

** Here what we do is, we grap the class lock which is there per a class.Static varibales are also per class.So our goal is attained.


  
Next PostNewer Post Previous PostOlder Post Home

0 comments:

Post a Comment