Iterator and threads

F

Frank Fredstone

If I have something like:

for (Object o : c) {
synchronized(o) {
// code that takes an hour to run
}
}

I assume another thread could remove the object referenced by o before
the synchronized block is entered, right? Even if c is
ConcurrentHashMap.keySet().

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?
 
T

Tom Hawtin

Frank said:
for (Object o : c) {
synchronized(o) {
// code that takes an hour to run
}
}

I assume another thread could remove the object referenced by o before
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
 
D

Daniel Pitts

If I have something like:

for (Object o : c) {
synchronized(o) {
// code that takes an hour to run
}

}

I assume another thread could remove the object referenced by o before
the synchronized block is entered, right? Even if c is
ConcurrentHashMap.keySet().

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?

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.
 
F

Frank Fredstone

Tom Hawtin said:
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).

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
 
F

Frank Fredstone

Daniel Pitts said:
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.

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
}
 
E

Esmond Pitt

Frank said:
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.
 
J

Joe Seigh

Frank said:
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
}

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,602
Members
45,185
Latest member
GluceaReviews

Latest Threads

Top