Use cases for Java concurrent utilities
concurrency, java, summary
Solution
- Why use a concurrent collection over a synchronized collection?
Because a `synchronized` collection only protects data from corruption due to concurrent access. This does not mean that the `synchronized` collections are optimized for concurrent access. Far from it, in fact - a `ConcurrentMap.putIfAbsent` is a much better mechanism for a `compareAndSet` than locking the entire `Map` for reads.
- When should the atomic classes be preferred over explicit locking?
The `AtomicInteger` and `AtomicLong` classes should always be used (in my opinion) over locking by hand with a primitive because they are more concise. Consider:
synchronized (lock) {
int old = counter;
counter++;
return old;
}
When compared with:
int old = counter.getAndIncrement();
I have to say though, that the classes suffer from their lack of waitability. For example, you often want some synchronized boolean where you `wait` on the boolean condition. These were available as `WaitableBoolean` in the old Doug Lea concurrency library but they were jettisoned in `j.u.c`, I'm not sure why.
- When should Locks be used over synchronization?
This is a more complicated question because usage of `Locks` carries some overhead. In fact, it's often said that there's no pint in using a `ReadWriteLock` in typical cases. One scenario where locks must be used is where the locking of a resource and its unlocking cannot be done in the same lexical scope. `synchronized` is powerless to help in cases such as these.
- What are the alternatives to wait() and notify(), notifyAll()?
`await`, `signal` and `signalAll`
- When should a CompletionService be used?
A completion service is useful in the case where the consumption of a result of a computation does not need to be accessed at the point the computation was submitted but where it is important that the completion of the computation (or its result, or success) be known by your program. This might be, for example, to monitor the proportion of failed tasks (which threw exceptions), or it may be for resource cleanup.
Problem
I have read Java Concurrency in Practice and this is a great reference, but I would like to see a concise single page summary of the use cases of the java.util.concurrent package. For instance: - Why use a concurrent collection over a synchronized collection? - When should the atomic classes be preferred over explicit locking? - When should Locks be used over synchronization? - What are the alternatives to wait() and notify(), notifyAll()? - When should a CompletionService be used? What are the pros/cons and pitfalls to be aware of?