synchronization question

G

gk

Hi, i found an reference which says

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


IS EQUIVALENT TO

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




so, does Synchronizing a method locks the whole object ?




If thats case then...

say, i have a class

class Myclass
{


public void M1()
{
//code
}

synchronized void M2() {
//code
}

}


Now, say ...one thread T1 grabbed M2() ....now, at the same time,
suppose another thread T2 wants to get M1()....is it possible for T2 to
get M1() now or it will be locked ?
 
P

Patricia Shanahan

gk said:
Hi, i found an reference which says

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


IS EQUIVALENT TO

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




so, does Synchronizing a method locks the whole object ?

I don't know what you mean by "the whole object". The synchronized
keyword on an instance method synchronizes on the "this" object. The
synchronized keyword on a static method synchronizes on the Class object.

If thats case then...

say, i have a class

class Myclass
{


public void M1()
{
//code
}

synchronized void M2() {
//code
}

}


Now, say ...one thread T1 grabbed M2() ....now, at the same time,
suppose another thread T2 wants to get M1()....is it possible for T2 to
get M1() now or it will be locked ?

There is no locking of methods in Java. All synchronization is
associated with some object. Any thread that is in M2 prevents entry to
any block that is synchronized on the same Myclass instance. It does not
prevent entry to M1, because it is not synchronized on the Myclass instance.

If, on the other hand, M1 contained a block:

synchronized(this){
...
}

that block could not be entered while another thread is executing M2 for
the same Myclass instance.

Patricia
 
T

Thomas Hawtin

gk said:
Hi, i found an reference which says

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


IS EQUIVALENT TO

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




so, does Synchronizing a method locks the whole object ?

It is only for convenience that synchronized works on arbitrary objects.
All that matters is that you hold the same lock object when accessing
variables. Quite often it is desirable not to expose the lock, so we
have something like this:

class MyClass
private static class Lock { }
private final Object lock = new Lock();

@GuardedBy("lock")
private int x;

@GuardedBy("lock")
private int y;
....
public void foo() {
synchronized (lock) {
++x;
--y;
}
}
}

(
The peculiar Lock class is there because the class name appears in stack
dumps - if you press ctrl-\ (or ctrl-break in Windows) from the console.

@GuardedBy is a suggested annotation that denotes which lock to hold
while accessing a variable.
)

public void M1()
{
//code
}

synchronized void M2() {
//code
}
Now, say ...one thread T1 grabbed M2() ....now, at the same time,
suppose another thread T2 wants to get M1()....is it possible for T2 to
get M1() now or it will be locked ?

Note: Assuming the same object. synchronized is about objects, not
blocks of code.

As it stands there is no problem with T2 to execute M1. If however M1
contains synchronized (this), then it will block to acquire the lock.

(As a slight complication, if M2 calls this.wait(), then it will release
the lock until it wakes up.)

Tom Hawtin
 
E

Eric Sosman

gk wrote On 11/07/06 11:15,:
Hi, i found an reference which says

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


IS EQUIVALENT TO

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

Pretty much, yes. The generated bytecode may be a little
bit different, but the practical effect is the same.
so, does Synchronizing a method locks the whole object ?

Yes. Or no. Or, well, it depends what you mean.

When you synchronize on some object, Java guarantees
that no other thread can synchronize on that object at the
same time. That is *all* that Java guarantees (aside from
some esoteric but important points about memory visibility
and such). In particular, Java does not guarantee that the
object somehow becomes inaccessible to other threads: they
can still have references to it and they can still use those
references to get at the accessible fields and methods. The
only thing they cannot do is acquire the lock at the same
time you're holding it.

Therefore, "holding the lock" on an object means only
what the class' code says it means. If the class provides
a mixture of synchronized and unsynchronized methods, when
thread T1 synchronizes on the object it prevents T2 from
executing any of the synchronized methods, but T2 can still
use the unsynchronized methods without hindrance. In that
sense, synchronizing does not "lock the whole object."

On the other hand, each Java object has one and only one
lock; there is not a way to synchronize on just a part of
an object. In this sense, synchronization "locks the whole
object;" there's no "partial synchrony." (You can, of course,
choose to synchronize on the sub-objects that your target object
refers to, but then you have synchronized on those other
objects and not on the target object at all. From the point
of view of one single object, its lock is either held or not
held and there are no in-between states.)
If thats case then...

say, i have a class

class Myclass
{


public void M1()
{
//code
}

synchronized void M2() {
//code
}

}


Now, say ...one thread T1 grabbed M2() ....now, at the same time,
suppose another thread T2 wants to get M1()....is it possible for T2 to
get M1() now or it will be locked ?

M1 is not synchronized, so T2 can execute it even if T1
holds the object's lock.

Also, both T1 and T2 can execute M2 simultaneously on
different instances of Myclass: each Myclass instance has its
own lock, independent of any other locks.
 
M

Mark Rafn

gk said:
so, does Synchronizing a method locks the whole object ?

Nothing locks an object. Synchronization obtains a lock identified by the
object, and it guarantees state consistency across threads who've passed
through the same lock.
say, i have a class
class Myclass
{
public void M1()
{
//code
}
synchronized void M2() {
//code
}
}
Now, say ...one thread T1 grabbed M2()

I don't know what grabbing a method means. Say T1 is inside M2, and therefore
has a lock identified by this instance of Myclass (sometimes stated as "holds
a lock on the object", but that's a bit misleading).
....now, at the same time, suppose another thread T2 wants to get M1()

Wants to call M1()? Nothing stops it. It's not synchronized, so T2 never
attempts to acquire any lock and never blocks.
 
G

gk

Patricia said:
I don't know what you mean by "the whole object". The synchronized
keyword on an instance method synchronizes on the "this" object. The
synchronized keyword on a static method synchronizes on the Class object.



There is no locking of methods in Java. All synchronization is
associated with some object. Any thread that is in M2 prevents entry to
any block that is synchronized on the same Myclass instance. It does not
prevent entry to M1, because it is not synchronized on the Myclass instance.

If, on the other hand, M1 contained a block:

synchronized(this){
...
}

that block could not be entered while another thread is executing M2 for
the same Myclass instance.

ok....but if M1 had code like this..

synchronized(some_list){

//some more code
}


i think, now also T2 will run M1 ...right ? because the lock is not on
the SAME instance "this" but on some other instance "some_list"....so
it can be executed by M1 ......is this correct ?
 
G

gk

Patricia said:
I don't know what you mean by "the whole object". The synchronized
keyword on an instance method synchronizes on the "this" object. The
synchronized keyword on a static method synchronizes on the Class object.



There is no locking of methods in Java. All synchronization is
associated with some object. Any thread that is in M2 prevents entry to
any block that is synchronized on the same Myclass instance. It does not
prevent entry to M1, because it is not synchronized on the Myclass instance.

If, on the other hand, M1 contained a block:

synchronized(this){
...
}

that block could not be entered while another thread is executing M2 for
the same Myclass instance.

ok....but if M1 had code like this..

synchronized(some_list){

//some more code
}


i think, now also T2 will run M1 ...right ? because the lock is not on
the SAME instance "this" but on some other instance "some_list"....so
it can be executed by T2 ......is this correct ?
 
N

Nigel Wade

gk said:
ok....but if M1 had code like this..

synchronized(some_list){

//some more code
}


i think, now also T2 will run M1 ...right ? because the lock is not on
the SAME instance "this" but on some other instance "some_list"....so
it can be executed by T2 ......is this correct ?

Yes. Each thread is synchronizing on a different object, so they will both be
able to run at the same time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top