• Post Reply Bookmark Topic Watch Topic
  • New Topic

Synchronization on singleton object  RSS feed

 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a single object whose synchronized method is called from multiple threads. Inside this method I am calling wait() on another object.

I need clarification,if a thread goes inside this method and waits on the object inside, is it true than no other objects will be able to execute this method?. During a wait on an object does it release the other locks?.

Or Is this a perfect case of deadlock?.

Thanks.
[ May 16, 2006: Message edited by: Thirumurugan Mylrajan ]
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another question.. During a wait is it possible for the thread to get waken up spurriously . Is this same as Interrupted Exception?.

Thanks.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not sure I follow your first question. Are you synchronizing on the singleton and some other object? Or just one of the two? It might help to show some code here to make sure we're all talking about the same thing.

As for the second question, I'm not sure. I've heard that it's possible, but the source was unverified, and I've never observed it. A strict reading of the API and JLS implies the answer is no - but you know, every so often things don't behave exactly according to specs. However I think the most common cause of a so-called "spurious" wakeup is that if an instance is publicly accessible to other code, then that other code could always acquire a lock on the instance and then send a notify() - even if your code never sent such a signal. It's hard to be certain exactly what unknown code may be doing. Consequently, some people advocate that you never synchronize on any publicly-accessible object. Always use an instance you created yourself which is held in a private field (whether static or nonstatic). This greatly reduces the chance that anyone else can lock or notify() your object without you knowing about it.
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the comments.

I am trying to lock on two objects.

The outer object is a Arraylist which contains "lock objects" on which I wait on. Arraylist is a Singleton.



I want to synchronize the arraylist as when checking for the presence
of a lock object, I dont want any other changes to it.

There will be other threads which will have to search for the presence of
the lock object and remove it from the arraylist and notify the objects
waiting on it.

If this indeed causes a deadlock, it is ok if I set a flag and wait on
the lock object outside the synchronized block?.

Thanks.
[ May 16, 2006: Message edited by: Thirumurugan Mylrajan ]
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The alternative solution I suggest is as follows

Will this solve the problem?.

Thanks.
[ May 16, 2006: Message edited by: Thirumurugan Mylrajan ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the code you show (in your 6:05 post), only one object can enter the outer sync block, since "this" is a singleton, and nothing you do inside that block will release the lock on the singleton. In order to wait on this other lock object, you will need to synchronize on that object too. And when you wait on that object, you will release that lock, and reacquire it in order to resume executing after being notified. However calling lockObject.wait() only releases the lock on the lockObject; it does not release the lock on the singleton.

Does this cause deadlock? Not from what you've said so far. But it could, if the other thread that needs to issue the notify() will also acquire a lock on the singleton. (And it sounds like this may be the case.) Even if it's not a true deadlock, the fact that only one thread can be inside the sync block at a time will probably mean that this solution is not what you want here.

[TM]: it is ok if I set a flag and wait on the lock object outside the synchronized block?.

Yes - this is probably a much better solution for you. Generally it's risky to nest one sync block inside another, and usually it's preferable to exit one sync block before entering another. And especially you should avoid calling wait() within nested sync blocks unless you're really sure of what you're doing. There are some situations where it's possible and even necessary to nest sync blocks, but it requires careful analysis to avoid deadlock. Avoiding nested locks entirely is usually much easier and safer.
[ May 16, 2006: Message edited by: Jim Yingst ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[TM]: The alternative solution I suggest is as follows

[...]

Will this solve the problem?.


Probably. However - who sends the notify() or notifyAll() signal? And does anyone ever set flag = false? Those could create additional problems.

Since flag is mutable data which is accessed inside more than one thread, you should probably move the "if (flag == true)" check inside the second sync block. Otherwise you may sometimes get incorrect information.

Hope that helps...
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. But there is one catch in the second solution.

If we break the synchronized code then the operations are not guaranteed to be atomic. Another thread could just steal the CPU from this just in between the two sync blocks.

I am verifying if that affects my application.
[ May 16, 2006: Message edited by: Thirumurugan Mylrajan ]
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
[b][TM]: The alternative solution I suggest is as follows

[...]


Probably. However - who sends the notify() or notifyAll() signal? And does anyone ever set flag = false? Those could create additional problems.

Since flag is mutable data which is accessed inside more than one thread, you should probably move the "if (flag == true)" check inside the second sync block. Otherwise you may sometimes get incorrect information.

Hope that helps...


We are having a out of sync thread problem in this Message Thread.

When I was posting I did not seee your latest message..

There should no problem if the flag is a local variable right?. The notify() is sent by another method in the same class, nearly in the same way.

 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[responding to the 6:35 post]

Yes, that's exactly the sort of thing you need to consider. Perhaps (if there's a problem), you can add another flag so that the second block can check if it is still appropriate to call wait()? Or perhaps the existing flag takes care of this. Again, it depends who (if anyone) sets flag = false, and why.

Come to think of it, now would be a good time to (strongly) recommend Joshua Bloch's Effective Java. In particular see Item 50: Never invoke wait() outside a loop. Almost always, there's some condition that needs to be checked before you enter a wait(), and then rechecked after you exit it. On rare occasions it might be possible to replace the while with an if, but it's doubtful. I'm skipping detailed discussion of this point for now, because I think Bloch does a much better job than I have time for. And I strongly recommend the rest of the book too, on general principle. Only about 24 pages deal with threads, but it's good stuff, and the remaining pages areexcellent advice about other things you may not have thought about yet. If you don't want to run out and buy it yet, I recommend checking with co-workers (if you have any nearby). Chances are fairly good someone has a copy you can look at.
[ May 16, 2006: Message edited by: Jim Yingst ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[TM]: We are having a out of sync thread problem in this Message Thread.



[TM]: There should no problem if the flag is a local variable right?. The notify() is sent by another method in the same class, nearly in the same way.

Well that changes things, but most likely it replaces one problem with a different problem. The thing is: how would you know if the second thread had already sent the notify() signal, before the first thread entered the wait()? If you enter wait() after notify() was already sent, you may wait forever. Or time out if you use that version of wait(). Not good. Usually you need both threads to share some information (e.g. a flag) so that the thread-which-waits can determine whether the condition-it-waits-for has already occurred or not. Which is why I assumed that flag was not a local variable. For what you've described so far, it may be OK for flag to be local, but you will probably need some additional nonlocal variable to transmit the required information. And that nonlocal variable should only be accessed from inside sync blocks, because its purpose is to transmit info from one thread to another.
[ May 16, 2006: Message edited by: Jim Yingst ]
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:

The thing is: how would you know if the second thread had already sent the notify() signal, before the first thread entered the wait()? If you enter wait() after notify() was already sent, you may wait forever .. Usually you need both threads to share some information (e.g. a flag) so that the thread-which-waits can determine whether the condition-it-waits-for has already occurred or not.
[ May 16, 2006: Message edited by: Jim Yingst ][/QB]


In the code


The presence of the lock object on the Arraylist is the conditon for wait or notify. The flag is just a tempoary placeholder to separate the sync blocks.

Threads are becomming scary


Lot of issues which I never thought are coming up..
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All right, it looks like I probably read some of the earlier posts too quickly and missed some details. However I'm still not sure I understand just how these threads are related, and what they're intended to accomplish. However, I note that there's really no way that the line "if (flag == true)" will ever see a value of false, because if the arraylist had not contained the lock, an exception would have been thrown. So the flag seems to be completely redundant here. Or you could just replace "throw error" with "log error message" or something similar, and then the flag becomes useful again.

I hope that helps...
 
Thirumurugan Mylrajan
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your time Jim. I actually posted the partial code for unlock.


But here as you mentioned before, I is possible that at an instant when executing if, another thread might notify on the lock, leaving this wating forever.

Since I have the luxury of considering Java 1.5, I am looking at reentrant locks which might suit my purpose.

Thanks.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!