Java SE 8 For the Really Impatient, Note 9
1,660 words in 10 minutes
Chapter 6 Concurrency Enhancements
java.util.concurrent
is a mix of useful utilities for the application programmer and power tools for library authors, without much effort to separate the two.
Key points:
- Updating atomic variables has become simpler with the
updateAndGet/accumulateAndGet
methods. LongAccumulator
/DoubleAccumulator
are more efficient thanAtomicLong
/AtomicDouble
under high contention.- Updating entries in a
ConcurrentHashMap
has become simpler with thecompute
andmerge
methods. ConcurrentHashMap
now has bulk operationssearch
,reduce
,forEach
, with variants operating on keys, values, keys and values, and entries.- A set view lets you use a
ConcurrentHashMap
asSet
. - The
Arrays
class has methods for parallel sorting, filling, and prefix operations. - Completable futures let you compose asynchronous operations.
Atomic Values
java.util.concurrent.atomic
package provided classes for lock-free mutation of variables since Java 5. You can safely generate a sequence of numbers like below:
incrementAndGet
: atomically increments the AtomicLong
and returns the post-increment value.
If you want to make a more complex update, you have to use the compareAndSet
method. Suppose you want to keep track of the largest value that is observed by different thread.
Instead, compute the new value and use compareAndSet
in a loop.
If another thread is also updating largest
, it is possible the it has beat this thread to it. Then compareAndSet
will return false
without setting the new value. The loop tries again. Eventually, it will succeed replacing the existing value with the new one. The compareAndSet
method maps to a processor operation that is faster than using a lock.
In Java 8, you can use a lambda expression.
The accumulateAndGet
method takes a binary operator that is used to combine the atomic value and the supplied argument.
Also see getAndUpdate
and getAndAccumulate
the return the old value.
These methods are also provided for:
AtomicInteger
AtomicIntegerArray
AtomicIntegerFieldUpdater
AtomicLongArray
AtomicLongFieldUpdater
AtomicReference
AtomicReferenceArray
AtomicReferenceFieldUpdater
LongAdder
and LongAccumulator
can be used to solve the problem that a large number of threads accessing the same atomic values.
LongAdder
: composed of multiple variables whose collective sum is the current value. Multiple threads can update different summands, and new summands are automatically provided when the number of threads increases. Efficient when the value of the sum is not needed until after all work has been done. If you anticipate high contention, you should simply use a LongAdder
instead of an AtomicLong
. Call increment
to increment a counter, or add
to add a quantity, and sum
to retrieve the total.
|
|
increment
does not return the old value which would undo the efficiency gain.
LongAccumulator
: generalizes the idea to an arbitrary accumulation operaiton. Provide the operation and its neutral element in the constructor. Call accumulate
to incorporate new values. Call get
to obtain the current value.
Internally, the accumulator has variables a1, a2, …, an. Each variable is initialized with the neutral element.
When accumulate
is called with value v, then one of them is atomically updated as ai = ai op v, where op is the accumulation operation written in infix form. In the above example, a call to accumulate
computes ai = ai + v for some i.
The result of get
is a1 op a2 op … op an.
If you choose a different operation, you can compute maximum or minimum.
The operation must be associative and commutative, meaning that the final result must be independent of the order.
DoubleAdder
and DoubleAccumulator
work in the same way with double
values.
StampedLock
: can be used to implement optimistic reads. Not recommended to use locks.
First call tryOptimisticRead
, upon which you get a “stamp”. Read your values and check whether the stamp is still valid(no other thread has obtained a write lock). If so, you can use the values. If not, get a read lock (which blocks any writers).