Synchronized methods

Hi All,

I was going through the following document:

http://java.sun.com/docs/books/tutorial/essential/concurrency/locksync.html

please see the lines below in double quotes

"When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that

method's object and releases it when the method returns. The lock release occurs even if the return was

caused by an uncaught exception. "

As far as I know there are only one copy of methods of a particular class no-matter

what is the number of objects created for that class.

My question is if above statment is correct; then if there are 10 objects instantiated from a class

and I am trying to access a synchronized method of the class, how do other 9 objects access the rest of

the methos? I am a bit confused about how method and objects are treated by Java (rather the JVM).

Rgeards

[942 byte] By [ayusman_dikshita] at [2007-10-3 3:58:17]
# 1

> As far as I know there are only one copy of methods

> of a particular class no-matter

> what is the number of objects created for that

> class.

Correct.

> My question is if above statment is correct; then if

> there are 10 objects instantiated from a class

> and I am trying to access a synchronized method of

> the class, how do other 9 objects access the rest of

>

> the methos? I am a bit confused about how method and

> objects are treated by Java (rather the JVM).

If there are 10 objects, there are 10 locks. Locks are associated with objects, not methods.

public class MyClass {

public synhcronized foo() {}

public synchronized bar() {}

public baz() {}

}

If I have 10 objects--say mc1 through mc10, then while thread t1 is inside mc1.foo(), all of the following are true:

* No other thread can be in mc1.foo().

* No other thread can be in mc1.bar().

* Another thread can be in mc2.foo()--mc10.foo().

* Another thread can be in mc2.bar()--mc10.bar().

* Another thread can be in mc1.baz()--mc10.baz(). (Yes, even mc1.baz(), since it's not synced.)

jverda at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 2
Just think of the monitor/lock as a private field of the object that can't be accessed directly. Each object has its own copy for a method to work with, just as with all an object's data.
davidholmesa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 3

Each object has its own copy for a method to work with,

I am confused :-( , all these days I knew that there is only one piece of code for a method that has to be shared by all the objects, as "jverd" agreed only one copy of the method is kept by the JVM.

Kindly clarify.

ayusman_dikshita at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 4
The synchronization occurs on the object not the method.
ejpa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 5
what if the baz() method manipulates one of the critical class level variable? This will cause incosistency right!!
ayusman_dikshita at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 6

If by "critical class level variable" you mean something static and shared by all instances which can fail if multiple threads attempt to modify it at the same time, then declaring your method baz() as simply "synchronized" is not sufficient.

If the static variable is final (it can be mutated, but not reassigned to something else) then i'd use the object itself as its own monitor

something like

Class Biz {

private static final MutableThing thing = new MutableThing();

public void baz() {

synchronized( thing ) { thing.modify(); }

}

}

If it can be re-assigned as well as mutated i'd probably provide an extra static final object to use as the monitor instead, something like

Class Biz {

private static MutableThing thing = new MutableThing();

private static final Object thingMonitor = new Object();

public void baz() {

synchronized( thingMonitor ) { thing = new MutableThing(); }

}

}

sorabaina at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 7

There is one copy of the code but each object has its own data. The monitor is considered part of the data of the object.

A static synchronized method use the Class object's monitor to guard access to the static data. But as long as all code paths to the static data protect access to that data via the same lock, then it doesn't matter what object that is.

Message was edited by:

davidholmes

davidholmesa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 8

> what if the baz() method manipulates one of the

> critical class level variable? This will cause

> incosistency right!!

By "class level variable" I assume you mean "instance variable"--that is, a non-static member variable. If this is the case, then, yes, baz could cause inconsistencies if it modifies instance variables.

If instead you mean "class variable--a static member variable--then the answer is still yes, but there's more to it than that. Because other instances can see the same class variables (static member variables), two threads could both be in the same synchronized method on two different instances and cause inconsistencies in the class variable.

This last part may just add more confusion, and I apologize if it does. However, because you used the term "class level variable," I wanted to point out the difference between class variables (static) and instance variables (non-static).

jverda at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 9
> If by "critical class level variable" you mean> something static and shared by all instancesI hope they don't - I can't think of many legitimate reasons for changing a static variable in an instance method!
oxbow_lakesa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 10
> I hope they don't - I can't think of many legitimate> reasons for changing a static variable in an instance> method!Why not? I don磘 see any problem in doing that.
TheLoosera at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 11

> Why not? I don磘 see any problem in doing that.

You're right; I don't see any reason that an instance method cannot cause a static variable to be changed (eg. a counter or something), but probably best to do it by calling a static method from within the instance method. Then you could just synchronize the static method.

oxbow_lakesa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 12

This is a beginner problem:

The issue is the class lifecicle

Class -> new -> class instance

When a class is constructed using new several class instance methods are initialized (the monitor is one). new (the java vm, but for this will can thing is new) calls the class loader to fix any class dependencies, initializes the instance member variables then the constructor is invoked.

For each class instance is a monitor, so ten classes each have its own monitor

synchronized(this)

{

}

will access the monitor. But doing so has a problem, what is the problem?

candid_rodrigueza at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...
# 13

> When a class is constructed using new several class

> instance methods are initialized (the monitor is

> one).

Your description is confusing. You don't construct classes, you construct instances. Creating a class instance requires that the Class be loaded and initialized if it hasn't already been so. "instance methods" are not "initialized". The "monitor" is not an "instance method".

> For each class instance is a monitor, so ten classes

> each have its own monitor

You mean "ten class instances" presumably.

> synchronized(this)

> {

>

> }

>

> will access the monitor. But doing so has a problem,

> what is the problem?

What is the question?

davidholmesa at 2007-7-14 21:56:46 > top of Java-index,Core,Core APIs...