Confusion about synchronized methods

I wrote the code below to check class locks. It clarified my confusion about object locks and class locks.

class LockCheck

{

privateint id;

private String name;

privatestaticboolean staticChecked;

public LockCheck(int id, String name)

{

this.id = id;

this.name = name;

System.out.println(this +" object of LockClass created");

}

//Getters

publicint getId(){return id;}

public String getName(){return name;}

publicboolean isStaticChecked(){return staticChecked;}

//Setters

publicvoid setStaticChecked(boolean staticChecked){ this.staticChecked = staticChecked;}

//Function to lock class and hold it for 10 seconds.

publicstaticsynchronizedvoid lockClass()

{

System.out.println("class lock activated");

try

{

System.out.println(Thread.currentThread().getName() +" Thread sleeping for 10 sec.");

Thread.sleep(10000);

System.out.println(Thread.currentThread().getName() +" Thread woke up.");

}

catch (InterruptedException e)

{

System.out.println("Problem while Main Thread tried to sleep: " + e);

}

System.out.println("class lock released");

}

//Function to check class level member's lock

publicstaticvoid checkLockedClass()

{

System.out.println("Class Lock Checked: Class is accessable now");

}

//Function to check instance level member's lock

publicvoid checkObjectOfLockedClass()

{

System.out.println("Object Lock Checked: " + this.getName() +"(" + this.getId() +") object is accessable now");

}

//Normal Static method

publicstaticvoid staticMethod()

{

System.out.println("This Static Method is accessable now");

}

//override toString function.

public String toString(){return (this.getName() +"(" + this.getId() +")");}

};

class NewThreadimplements Runnable

{

private Thread lockThread;

private LockCheck lockCheck;

public NewThread(String threadName, LockCheck lockCheck)

{

this.lockCheck = lockCheck;

lockThread =new Thread(this, threadName);

System.out.println("Thread Created: " + threadName +" with object - " + lockCheck);

lockThread.start();

}

publicvoid run()

{

try

{

System.out.println(lockThread.getName() +" Thread sleeping for 2 sec.");

Thread.sleep(2000);

System.out.println(lockThread.getName() +" Thread woke up.");

}

catch (InterruptedException e)

{

System.out.println("Problem while " + lockThread.getName() +" Thread tried to sleep: " + e);

}

lockCheck.checkObjectOfLockedClass();

if(!lockCheck.isStaticChecked())

{

lockCheck.checkLockedClass();

lockCheck.setStaticChecked(true);

LockCheck.staticMethod();

//Synchronized method to be called here

}

System.out.println(lockThread.getName() +" Thread with object - " + lockCheck +" Exiting...");

}

};

publicclass ClassLockTest

{

publicstaticvoid main(String[] args)

{

//create two LockCheck objects.

LockCheck lc1 =new LockCheck(1234,"FirstLockCheck");

LockCheck lc2 =new LockCheck(5678,"SecondLockCheck");

//Create two separate threads for created objects.

NewThread t1 =new NewThread("FirstThread", lc1);

NewThread t2 =new NewThread("SecondThread", lc2);

//lock class for 10 seconds.

LockCheck.lockClass();

System.out.println("Main Thread Exiting...");

}

};

the output of this program is:

- Run -

FirstLockCheck(1234) object of LockClass created

SecondLockCheck(5678) object of LockClass created

Thread Created: FirstThread with object - FirstLockCheck(1234)

Thread Created: SecondThread with object - SecondLockCheck(5678)

class lock activated

main Thread sleeping for 10 sec.

FirstThread Thread sleeping for 2 sec.

SecondThread Thread sleeping for 2 sec.

FirstThread Thread woke up.

Object Lock Checked: FirstLockCheck(1234) object is accessable now

Class Lock Checked: Class is accessable now

This Static Method is accessable now

FirstThread Thread with object - FirstLockCheck(1234) Exiting...

SecondThread Thread woke up.

Object Lock Checked: SecondLockCheck(5678) object is accessable now

SecondThread Thread with object - SecondLockCheck(5678) Exiting...

main Thread woke up.

class lock released

Main Thread Exiting...

Output completed (10 sec consumed) - Normal Termination

But when we replace the line

//Synchronized method to be called here

By

LockCheck.lockClass();

then the output is:

- Run -

FirstLockCheck(1234) object of LockClass created

SecondLockCheck(5678) object of LockClass created

Thread Created: FirstThread with object - FirstLockCheck(1234)

Thread Created: SecondThread with object - SecondLockCheck(5678)

class lock activated

main Thread sleeping for 10 sec.

FirstThread Thread sleeping for 2 sec.

SecondThread Thread sleeping for 2 sec.

FirstThread Thread woke up.

Object Lock Checked: FirstLockCheck(1234) object is accessable now

Class Lock Checked: Class is accessable now

This Static Method is accessable now

SecondThread Thread woke up.

Object Lock Checked: SecondLockCheck(5678) object is accessable now

SecondThread Thread with object - SecondLockCheck(5678) Exiting...

main Thread woke up.

class lock released

class lock activated

FirstThread Thread sleeping for 10 sec.

Main Thread Exiting...

FirstThread Thread woke up.

class lock released

FirstThread Thread with object - FirstLockCheck(1234) Exiting...

Output completed (20 sec consumed) - Normal Termination

So I concluded from here, that there is no class lock, there is only resource lock.

And resources of a class are its object and its static methods, as they are having their separate existance.(although they are linked together).

That means, Objects are having their own separate monitors,

and static methods are having their own separate monitors.

Am I right?

And when we access something in a synchronized block, for eg some third party class, then, if synchronized block is in an instance method then that object's monitor is locked.

and if synchronized block is in a static method, then that static method's monitor is locked.

Am I right? -> or the third partiy's created object's monitor is locked.

Thanks in advance for any guidance.

[10911 byte] By [Sumit_Tyagia] at [2007-11-26 14:55:16]
# 1

I have not read all of your code, but I noticed that only one static method is synchronized. While this method is executing no other thread will be able to enter the same method, but it will be able to enter the other static methods of the class. Are you using checkLockedClass to check that? Then that needs to be synchronized too.

Look at it this way. You know the class called Class right? Think that every java object has a static reference to a Class object, the class of which it is an object. When you enter a static method, this is the object that is locked.

To enter a synchronized block, *something* needs to be locked:

- for synchonized(expr) it is the object that the expression evaluates to

- for a synchronized instance method, it is the instance of which the method is to be executed

- for a synchronized static method, it is the Class object as explained above

hth

Message was edited by:

hemalpandya

hemalpandyaa at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 2

>>- for a synchronized static method, it is the Class object as explained above

Class object represents the runtime state of any object.

Now if class object is locked then, everything related to its runtime should be locked!

But it is not happening, only the synchronized method is being locked.

That means every static method must be having its own separate lock.

(as I think)

But your reply enhanced my confusion!

Sumit_Tyagia at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 3

> >>- for a synchronized static method, it is the Class

> object as explained above

>

> Class object represents the runtime state of any

> object.

> Now if class object is locked then, everything

> related to its runtime should be locked!

> But it is not happening, only the synchronized method

> is being locked.

> That means every static method must be having its own

> separate lock.

> (as I think)

>

> But your reply enhanced my confusion!

hemalpandya is correct. a synchronized static method locks on the class object of that class. e.g. a syncrhonized method in the class A will lock on A.class. You can still execute other static methods if they aren't synchronized. It's the same as with normal methods.

Kaj

kajbja at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 4

Kaj gives a good explanation. I will try too...

> >>- for a synchronized static method, it is the Class

> object as explained above

>

> Class object represents the runtime state of any

> object.

> Now if class object is locked then, everything

> related to its runtime should be locked!

You misunderstand the meaning of being locked. All it means is that while one threads T1 holds the lock on some object O any other thread T2 that wants to lock that object O will wait until the T1 releases its lock on O.

In case of synchronized static methods it is the class object that is locked. So while one synchronized static method M1 of a class C is executing in thread T1 no other thread can enter any synchronized static method of that class C will. T1 will release the lock when C.M1 completes execution at which point the other thread can enter any other synchronized static method of C, including M1 itself.

While T1 is executing this C.M1, you won't be able to enter any block that explicitly locks this class object either, such as the following:

synchronized (C.class) {

....

}

I don't think I have tried this, at least not recently. But I am pretty sure that's how it is.

> But it is not happening, only the synchronized method

> is being locked.

Correct. As I explain above.

> That means every static method must be having its own

> separate lock.

> (as I think)

Nope.

>

> But your reply enhanced my confusion!

Now I can't give up till it is subdues....

hemalpandyaa at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 5

>>You misunderstand the meaning of being locked.

hemalpandya! you are right! I misunderstand the concept.

Thanks for ur and Kaj's support.

I have one more confusion here.

are all the non-static synchronized methods locked too, when class lock is aquired, (as objects spawned from the class only), or only static synchronized methods are locked.

Thanks for your support.

Sumit_Tyagia at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 6

> >>You misunderstand the meaning of being locked.

>

> hemalpandya! you are right! I misunderstand the

> concept.

>

>Thanks for ur and Kaj's support.

You are welcome.

>

> I have one more confusion here.

How about the last one; is that cleared?

> are all the non-static synchronized methods locked

> too, when class lock is aquired, (as objects spawned

> from the class only), or only static synchronized

> methods are locked.

I have to take the question back. I see it is still not cleared. Methods cannot be locked. Only objects can be locked. A code body that is synchronized can be entered by a thread only when that thread is able to acquire lock on whatever object it is supposed to.

So in case of

- static synchronized method, the class object (getClass()) has to be locked

- instance synchronized method the object on which the method is called (this) has to be locked

- code of the form

synchronized (<expression>) { .... }

the object that the expression evaluates to has to be locked.

Now you tell me can a thread enter a synchronized static method while another thread is executing a synchronized instance method?

>

> Thanks for your support.

hemalpandyaa at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 7

> I have one more confusion here.

> are all the non-static synchronized methods locked

> too, when class lock is aquired, (as objects spawned

> from the class only), or only static synchronized

> methods are locked.

No. You're imagining much more complexity that there really is. Locks are very simple, there's no such thing as a "class lock," and all locks work the same way.

When one thread hold a lock (acquired by entering a synchronized block on that lock), then no other thread can obtain that lock, and any thread that tries will stop until the lock becomes available, either by the first thread leaving the sync block, or by the first thread calling wait().

Every object has one lock associated with it, and you obtain that lock by doing synchronized (someObject).

You don't lock methods or classes or anything like that. Holding the lock only means that other threads must wait until you release that lock before they obtain it. That's all.

class Foo {

synchronized void bar() { /* body */ }

// is shorthand for

void bar() { synchronized(this) {/* body */ } }

// and

static synchronized bar() { /* body */ }

// is shorhand for

static bar() { synchronized(Foo.class) { /* body */ } }

There's nothing special about static synced methods. They just obtain a single object's lock, just like any other synced method or block.

jverda at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...
# 8
Thanks to all of you!I got the point now!"locks are associated with objects"
Sumit_Tyagia at 2007-7-8 8:43:46 > top of Java-index,Java Essentials,Java Programming...