• 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

Dan's answer on synchronization & locks

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Answer#15 on Dan's Thread Exercise-2 states:
"A local variable (that is an object reference) can not be used to synchronize threads because each thread has its own copy of local variables and their locks."
Then why does the code below, using a local String variable work when trying to synchronize.
class GetLock implements Runnable {
public void run() {
String lock = "";
synchronized (lock) {
for (int i = 0; i<15; i++)
{
System.out.print(Thread.currentThread().getName() + 1);
System.out.print(Thread.currentThread().getName() + 2);
System.out.print(Thread.currentThread().getName() + 3);
}
}
}
public static void main (String[] args) {
new Thread(new GetLock (), "A").start();
new Thread(new GetLock (), "B").start();
}
}
Output is always: A1A2A3A1A2A3....B1B2B3B1B2B3...
i.e Thread "B" starts only after Thread "A" releases the lock, but the lock is a local object

[ June 11, 2003: Message edited by: Smita Sinha ]
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Smita Sinha:
Then why does the code below, using a local String variable work when trying to synchronize.
...
Output is always: A1A2A3A1A2A3....B1B2B3B1B2B3...
i.e Thread "B" starts only after Thread "A" releases the lock, but the lock is a local object


Why does it work? Sheer luck. Or, sheer luck and fast computers.
The synchronized label is accomplishing nothing in this situtation. Don't believe me, comment it out and see what you get. I got the same output whether it was in there or not.
What is happening is that the first thread is started and, before it is timesliced out, it has completed all 15 iterations of its loop. Then, the next thread starts and it completes its 15 iterations. You're performing fairly short operations so it's doubtful that you'd see a timeslice cause a problem. If you were to let these loops go on infinitely, you may see some anomolies, but, of course, you'd have to look through an infinite amount of output to find it, too. :roll:
The key here is that every object has its own lock which can be obtained for synchronization purposes. Since you have created two instances of the class GetLock and each instance has its own instance of the String lock, you have two different instances of that String - one for each GetLock instance. Therefore, rather than both threads fighting for teh lock of a single object, they're getting locks from separate objects and will never fight over a lock.
As each thread is obtaining the lock from a local variable, there will never be a case when the thread tries to obtain the lock and won't be able to.
I hope that helps,
Corey
 
Smita Sinha
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This code snippet was from Question#17, Dan's Thread Exercise-2. The answer on Dan's site claims that there is only one object for both threads even though the object used as a lock is a local variable. This is because the local variable refers to an object in the string pool.
Does that mean that there is an exception case when we use local objects for synchronization.
Are there any more cases that fall under this exception. (i.e maybe if the local reference is passed back from the method and points to a live object in the heap?)
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oops. I wasn't paying close enough attention, I guess. The fact that you're trying to synchronize on a String literal does make a difference. Because of the way String literals are handled (there is a constant pool of them), each object will have a reference to the same String object referenced from the pool. So, in this case, the synchronization is working properly, although I doubt you'd want to synchronize on a String literal very often.
Sorry about the confusion. But, as far as I know, Strings are the only objects that are treated this way. If I'm incorrect, someone please let me know, but String literals should be the only "exception" to the rule.
 
Smita Sinha
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. I too hope that String literals are the only exception.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic