This week's book giveaway is in the Jython/Python forum.
We're giving away four copies of Murach's Python Programming and have Michael Urban and Joel Murach on-line!
See this thread for details.
Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Thread locking question  RSS feed

 
William Smith II
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A couple questions about threads.

1. When this code executes, what happens?

String a = new String("temporary string");
synchronized(a) {
a = new String("second temporary string");
while(true) {
// more code here //
}
}

I think the lock should be lost since a new "a" object is
created but the synchronized code is still executing. Is this correct?



2. When you have a lock on an object by using synchronized(objectA),
are all the instance objects locked of objectA locked
as well?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1) Your synchronized block will keep the lock on the original object. It doesn't matter that the variable "a" no longer points to that object. If another thread synchronizes on "a" after you change the variable to point to a new object, it will lock on the new object. That may or may not be a Good Thing.

2) If you lock on an object instance, you lock on just that one object instance. Are you asking about the objects referenced by member variables in that object? There's no lock on those unless somebody makes one.

Hope that helped. Visit the Threads forum if you want to dig into this kind of thing in more detail.
[ May 29, 2007: Message edited by: Stan James ]
 
William Smith II
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
1) Your synchronized block will keep the lock on the original object. It doesn't matter that the variable "a" no longer points to that object. If another thread synchronizes on "a" after you change the variable to point to a new object, it will lock on the new object. That may or may not be a Good Thing.

2) If you lock on an object instance, you lock on just that one object instance. If you synchronize on a static variable or synchronize a static method, those things belong to the class and are shared by all instances of the class.

Hope that helped. Visit the Threads forum if you want to dig into this kind of thing in more detail.


Thanks for the quick reply. I should have known for #1 since that's straight from the SCJP exam! #2 I was right on.

Here's another question:
3.
String objectA = new String[100];
synchronized(objectA) {
// code here
}

How do I prevent processB from allocating a new array object before processA has the opportunity to enter the synchronized section? Is there a more elegant way of doing this?


Moderator: if you could move this to the thread forums. Thanks.
 
Qunfeng Wang
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about invoking processA.join() in processB? Then processB will wait until processA finished.
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by William Smith II:
How do I prevent processB from allocating a new array object before processA has the opportunity to enter the synchronized section? Is there a more elegant way of doing this?

I would think you intend "... prevent Thread(n)from allocating a new array object before Thread(0) has the opportunity to enter the synchronized section ? "

The general answer is to place synchronized() at entry to anything that can be entered by two threads. synchronized{} can be placed close to variable accesses if performance is an issue. But I think we have isolated an important, fundamental question here. If there is not much difference between an Object and a Thread, then how can it be that it is not the "instances" that are busy, it's the *underlying threads* ?

See: Failure mode of two reference calls to one thread in which I ultimately went back and admitted I had the question wrong.

Typically the answer is to place the synchronization at a higher level than it was before. - JY in Topic: Thread question

Aside from the fact that Study Guides seem to be consistent in saying that Strings are unmodifiable, we do have the question of allocating a new array as you do, which are modifiable (because the are a reference ?) and then your code: char[] c = new char[100];//modified by me to suit my next point \r would make c point to a new array when Thread(n) arrived at that nexus in the code path, and we would have an identifiable failure mode.

More generally, so that I can understand it:

Or maybe Interface Map<K,V> repository;

Just any variable that allows us to get to your central question:How do I prevent processB from allocating a new array object before processA has the opportunity to enter the synchronized section?

Well the way this is done is with the synchronized keyword and it, as I recently discovered, has to be "put in both places" IOW - that could be numerous places in one's code. It does not do any good if you have a reference of class g passed into the constructor of class h unless you have a synchronized(g) in an instance method call or static method call in class h (I think)

Variable naming can get us in a house of mirrors here and camp convention is to make the names indicative of what is going on, but I have not seen an admission of the fact that threads are what actually runs the machine.

currentThread(}.toString() got me my first test results that told me what was actually going on in my prototyping, I had been instructed that They make it alot easier to understand the code at first glance, and are really not that hard to come up with:, which is fine as a design goal .... once you get the machine running.

But OO does not write code, you do. And your code does not drive the machine, Threads do. Your code describes an execution path. Threads follow that path.

There is a tradeoff between speed, simplicity and reliability. Today's machines are so fast that hand-tweaking to ultra-tight code should be reserved to later development phases, if done at any point. The elegant solution is what Jim suggests: Typically the answer is to place the synchronization at a higher level than it was before.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!