• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

synchronized method

 
Ranch Hand
Posts: 152
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if i have a class with 2 synchronized methods says methA() and methB().if i create 2 thread objects say t1 and t2.now t1 is accessing methA().can t2 access methB()?kindly explain
 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Clyde,
Keep in mind each object instance has a single lock.
And there is a one class-wide lock for static synchronized methods.
When "t1" calls "methA()" t1 owns the object lock;
Now if t2 has to call "methB()" it must get the lock,
but as "t1" already owns it so "t2" has to wait for "t1" to release the lock...
 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if your methods are static only one obejct can avail class-level lock.

but if your methods are not static and if you have two diff. objects, then both objects can enter into the synchronized method simultaneously. this is object-level lock.
 
clyde melly
Ranch Hand
Posts: 152
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
so the conept of static comes into picture.if the synchronized method is static,then t2 has to wait to get the lock.If non static no problems.am i right or i have misunderstood???
 
Ranch Hand
Posts: 116
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by clyde melly:
so the conept of static comes into picture.if the synchronized method is static,then t2 has to wait to get the lock.If non static no problems.am i right or i have misunderstood???



Yes, if the method is static, the lock is on the class. If the method is not static, the lock is on the instance of the class. Your statement above is correct.
Jeff Walker
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Lemme explain with the following scenario, for proof I'll also attach code with it.

Let objA be an object with two methods:

1. public void call(String callerThreadName)
2. public synchronized void callSync(String callerThreadName)

Let C1 & C2 be two threads that have access to objA.

If C1 accesses objA via the synchronized method, C2 can still call the unsynchronized method of objA and change the state of the variable.

When C1 calls the synchronized method it sleeps, so that it holds on to the lock for a while ensuring that we can make C2 call the other method in the mean time. If during this time C2 accesses the other method and changes the state of objA then the above hypothesis is correct. This is indeed what happens.

Here is the full code:

class A
{
String lastAccessedBy;

public void call(String callerThreadName)
{
lastAccessedBy = callerThreadName;
System.out.println("Call By : " + callerThreadName);
}

public synchronized void callSync(String callerThreadName)
{
lastAccessedBy = callerThreadName;
System.out.println("In Sync Method - " + callerThreadName);
try {
if (callerThreadName.equals("C1"))
{
Thread.sleep(1000);
}
} catch (Exception e) {}
System.out.println("Wait Over -- Call Sync. By : " + callerThreadName + " -- last Accd By " + lastAccessedBy);
}

A()
{
System.out.println("A Constr.");
}
}

class B
{
B()
{
System.out.println("B Constr.");
}

public static void main(String[] argv)
{
A objA = new A();

C objC1 = new C("C1", objA);
C objC2 = new C("C2", objA);
Thread t1 = new Thread( objC1 );
Thread t2 = new Thread( objC2 );
t1.start();
t2.start();
}
}

class C implements Runnable
{
int x = 1;
String name;
A objA;

public void run()
{
while (x>0)
{
System.out.println("-- " + name);

try {
objA.call( name );
objA.callSync( name );
objA.call( name );
this.wait();//Optional in this case
} catch(Exception e) {}
x--;
}
}


C()
{
System.out.println("C Constr.");
}

C(String name, A objA)
{
this.name = name;
this.objA = objA;
System.out.println(name + " Constr.");
}
}

Output --------------------
C:\JavaProgs>java B
A Constr.
C1 Constr.
C2 Constr.
-- C1
Call By : C1
In Sync Method - C1
-- C2
Call By : C2
Wait Over -- Call Sync. By : C1 -- last Accd By C2
In Sync Method - C2
Wait Over -- Call Sync. By : C2 -- last Accd By C2
Call By : C2
Call By : C1

...Observe the 4th line from the last:
Wait Over -- Call Sync. By : C1 -- last Accd By C2

It implies that C2 called the unsynchronized method in the mean time and by the time the synchronized method called by CV1 finished, the state of the variable was altered by C2.

...Now The above is something I'm sure of, but raises a question. If the locking is at object level (no static used here so we are not talking about class level locking or whatever) then how on earth is the object member still modifiable when the other thread has still got a hold of it?

Note: Even if you replace Thread.sleep() by some other code that consumes time, it still gives the same result.

Also, only if both methods are synchronized then the member variable remains thread safe.
 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

how on earth is the object member still modifiable when the other thread has still got a hold of it?



The other thread has a hold of it as a monitor, that's all. Synchronization does not lock an object. It locks a method or code block, using an object as a monitor, which is just a kind of token.
 
Arjun Dhar
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If Synchronization does not lock an object then how do I obtain a true lock over an object? If I understand what you've mentioned then using an object inside the synchronized block is also not locking it. So how do I truely obtain a lock on an object??

Adding to the above I found the following from http://www.javaworld.com/javaworld/jw-07-1997/jw-07-hood.html:

When a thread arrives at the first instruction in a block of code that is under the watchful eye of a monitor, the thread must obtain a lock on the referenced object.

Doesn't this imply, that obtaining the monitor directly or indirectly obtains the lock since in the JVM locks in conjunction with monitors? So in other words

if "The other thread has a hold of it as a monitor" then
=> The other thread has locked the object.

Sorry, am confused about this.
 
Alan Walker
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The terminology can be confusing - or at least I have found it so. But I think it is fairly clear how the synchronization mechanism works, even if we are unclear about what exactly is meant by "monitor" or "lock".

Just before the passage you quoted from Bill Venners' article in JavaWorld is this sentence: "Each monitor is associated with an object reference." This is the object whose lock must be obtained. It could be any object referenced by a synchronized statement, not necessarily the object containing the code we are synchronizing.

Here are some quotes from the Java Language Reference that might help:

To synchronize threads, the Java programming language uses monitors, which are a high-level mechanism for allowing only one thread at a time to execute a region of code protected by the monitor. The behavior of monitors is explained in terms of locks; there is a lock associated with each object.

- Chapter 17

Acquiring the lock associated with an object does not of itself prevent other threads from accessing fields of the object or invoking unsynchronized methods on the object. Other threads can also use synchronized methods or the synchronized statement in a conventional manner to achieve mutual exclusion.

- Chapter 14

The last sentence is the answer to your question, how to obtain a lock on an object. To protect an object's instance data, you must establish appropriate synchronization of the code accessing the data. There is no simple solution, alas (as you have demonstrated).
 
Arjun Dhar
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, the last quote is indeed an acknowledgement of that. Thanks for your replies.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic