> for (Object o : c) {
> synchronized(o) {
[quoted text clipped - 5 lines]
> the synchronized block is entered, right? Even if c is
> ConcurrentHashMap.keySet().
The object could be removed even within the synchronised block.
What may be useful is double check within the synchronised block whether
the object is still in the map, and synchronise on the object around
every point where it could be removed from the map (clear and removeAll
may be tricky).
> If that's true and I can't have other threads wait for the entire
> collection to be iterated over, I guess Iterator would be the wrong
> choice. Is that right?
Depends upon what you are trying to achieve.
Often a ConcurrentMap will have values that are synchronised upon.
Future (or Future-like types) are also quite popular.
Tom Hawtin
Frank Fredstone - 23 Apr 2007 06:52 GMT
>> for (Object o : c) {
>> synchronized(o) {
[quoted text clipped - 12 lines]
> around every point where it could be removed from the map (clear and
> removeAll may be tricky).
Hmm. So, within the for loop, before the synchronized construct, I
have a reference to an object. If another thread removes the object
from the collection, I will still have an object to synchronize on,
even if all other threads have set their references to it to null and
it's no longer in the collection, is that right?
Frank
>> If that's true and I can't have other threads wait for the entire
>> collection to be iterated over, I guess Iterator would be the wrong
[quoted text clipped - 6 lines]
>
> Tom Hawtin
Esmond Pitt - 23 Apr 2007 09:13 GMT
> Hmm. So, within the for loop, before the synchronized construct, I
> have a reference to an object. If another thread removes the object
> from the collection, I will still have an object to synchronize on,
> even if all other threads have set their references to it to null and
> it's no longer in the collection, is that right?
Yep. There's nothing that can change the value of your 'o' between the
for-loop and the synchronized() block, or anywhere else in your method
either.
> If I have something like:
>
[quoted text clipped - 12 lines]
> collection to be iterated over, I guess Iterator would be the wrong
> choice. Is that right?
It could be removed after you get the reference too it. Your reference
will still be valid, so thats not a problem.
The question I have is, why do you need to synchronize for an hour.
Actually, I'm guessing thats an exaggeration, but the concept is the
same. You should try to synchronize around the minimum size block that
you can while maintaining correctness.
Frank Fredstone - 23 Apr 2007 06:55 GMT
>> If I have something like:
>>
[quoted text clipped - 19 lines]
> same. You should try to synchronize around the minimum size block that
> you can while maintaining correctness.
Okay, I was thinking the reference o would become invalid.
As far as synchronizing for an hour, probably more like:
for (Object o : c) {
synchronize(o) {
// do something
}
// code that runs for an hour
}
Joe Seigh - 23 Apr 2007 11:32 GMT
>>>If I have something like:
>>>
[quoted text clipped - 30 lines]
> // code that runs for an hour
> }
The enumeration only returns objects that were in the hashmap at some point,
though not necessary at the current time. Also you may not get all the objects
that were in the hashmap at some point in time. And while synchronizing the objects
themselves may be useful in the context of the object itself, it has no effect on
operations on the hashmap itself. Objects can be added or removed from the hashmap
while you hold the object monitor lock, including the locked object which could be added
and removed any number of times, though you will probably only see any object at
most once during an iteration.

Signature
Joe Seigh
When you get lemons, you make lemonade.
When you get hardware, you make software.