Excluding concurrent activity from a concurrent Java collection

248 Views Asked by At

Joshua Bloch's Effective Java, Second Edition, item 69 , states that

[...] To provide high concurrency, these implementations manage their own synchronization internally (Item 67). Therefore, it is impossible to exclude concurrent activity from a concurrent collection; locking it will have no effect but to slow the program.

Is this last statement correct? If two threads lock the collection and perform several operations within that lock, these operations might still be interleaved?

For the statement to be correct I would expect that either these collections run threads internally with which you cannot synchronize, or they somehow "override" the standard synchronization behavior such that a statement like synchronized(map){ ... } behaves different than on a 'normal' object. From the answers/comments to related questions I think neither if these is true:

To avoid possible misinterpretation:

  • I'm aware that concurrent collections are designed exactly to avoid this global locking, my question is whether it's possible in principle
  • I find Effective Java an excellent book and I'm just seeking clarity on a particular item.
2

There are 2 best solutions below

1
On

Sources suggest that ConcurrentHashMap uses an internal mechanism for locking (static final class [More ...] Segment<K,V> extends ReentrantLock) and does not therefore use any synchronized methods for it's locking mechanism.

It should therefore be simple to use the Map as a lock and synchronize on it - in the same way you could use a new Object() or your own ReentrantLock. However, it would not affect the inner workings of the Map which is - I think - what he is trying to say.

0
On

This might clarify it (hint from another Item 67):

It is not possible for clients to perform external synchronization on such a method because there can be no guarantee that unrelated clients will do likewise.

Your code is a client to these internally-synchronized concurrent implementations. Even if you use external lock (to slow yourself down), other clients may not and will still execute internal implementation concurrently.