Monday, December 20, 2004

Understanding what is locked when using the synchronized keyword.

I wanted to put on paper, the exact meaning of what is locked when the synchronized keyword is used.

What I had read and heard discussed was that the Object is locked when a thread enters a synchronized method in a class. Now that will lead one to believe that the entire Object is locked.

Let us see.

Here is a class with a synchronized method “a”and a non synchronized method “b”.

public class Methods {

public synchronized void a(){

while(true){

System.err.println("a");

System.out.println("Thread.currentThread()" + Thread.currentThread());

}

}

public void b(){

while(true){

System.err.println("b");

System.out.println("Thread.currentThread()" + Thread.currentThread());

}

}

}

Here is class that gives singletons of the above class

public class MethodsFactory {

public static Methods m = null;

public static synchronized Methods getMethodsInstance(){

if(m == null){

m = new Methods();

}

return m;

}

}

Here are two Threads classes A and B that call the above factory and get the same instance of the Methods class, but call method a and b respectively. remember a is synchronized and b is not.

import java.util.List;

public class ThreadCallA extends Thread {

public void run() {

Methods m = MethodsFactory.getMethodsInstance();

m.a();

}

}

import java.util.List;

public class ThreadCallB extends Thread {

public void run() {

Methods m = MethodsFactory.getMethodsInstance();

m.b();

}

}

Now here is the main Test class.

public class Threadtest {

public static void main(String[] args) {

Thread TA = new ThreadCallA();

TA.setName("TA");

TA.start();

Thread TB = new ThreadCallB();

TB.setName("TB");

TB.start();

}

}

Here is the result.

a

Thread.currentThread()Thread[TA,5,main]

a

Thread.currentThread()Thread[TA,5,main]

a

Thread.currentThread()Thread[TA,5,main]

a

Thread.currentThread()Thread[TA,5,main]

b

Thread.currentThread()Thread[TB,5,main]

b

Thread.currentThread()Thread[TB,5,main]

b

Thread.currentThread()Thread[TB,5,main]

b

Thread.currentThread()Thread[TB,5,main]

a

Thread.currentThread()Thread[TA,5,main]

b

Thread.currentThread()Thread[TA,5,main]

So even though method a() locks the object another thread can call method b() !.

This is because b() is not synchronized.

So what is a lock ? The lock just locks all synchronized code in an Object. On the static side any class is an instance of "Class", so the same applies there too.

Now if you synchronize b(), then b() will also be locked when a() is called.

And in our case due to us having “while(true)”, whichever thread gets to one of the methods first will be the only thread executing and the other thread will never get to the other synchronized method. Try it !,

Now if you have a static method, that method can still be called when there is a lock due to an instance method

0 Comments:

Post a Comment

<< Home