New in Guava 21 common.util.concurrent – Guava 21 common.util.concurrent中的新功能

最后修改: 2017年 4月 1日

1. Introduction


In the previous article, we started exploring the new functionality introduced in the common.collect package.


In this quick article, let’s walk through additions to the common.util.concurrent package.


2. AtomicLongMap


In concurrent scenarios, standard HashMap might not really work well, as it’s simply not concurrent. In this particular scenario, AtomicLongMap bails you out by storing Long values in a thread-safe way.


AtomicLongMap was introduced a long time ago in Guava 11. Now, four new methods have been added.

AtomicLongMap很早以前就在Guava 11中被引入。现在,又增加了四个新方法。

2.1. accumulateAndGet()

2.1. accumulateAndGet()

accumulateAndGet() method updates the value linked with the key by merging it up with existing value using the accumulator function. Then, it returns the updated value:


public void accumulateAndGet_withLongBinaryOperator_thenSuccessful() {
    long noOfStudents = 56;
    long oldValue = courses.get(SPRING_COURSE_KEY);

    long totalNotesRequired = courses.accumulateAndGet(
      (x, y) -> (x * y));

    assertEquals(totalNotesRequired, oldValue * noOfStudents);

2.2. getAndAccumulate()

2.2. getAndAccumulate()

This method has the similar functionality as defined above but, it returns the old value instead of the updated value( as the order of operations in the same suggests).


2.3. updateAndGet()

2.3. updateAndGet()

updateAndGet() method updates current value of the key using the specified function provided as the second parameter. Then, it returns updated value of the key:


public void updateAndGet_withLongUnaryOperator_thenSuccessful() {
    long beforeUpdate = courses.get(SPRING_COURSE_KEY);
    long onUpdate = courses.updateAndGet(
      (x) -> (x / 2));
    long afterUpdate = courses.get(SPRING_COURSE_KEY);

    assertEquals(onUpdate, afterUpdate);
    assertEquals(afterUpdate, beforeUpdate / 2);

2.4. getAndUpdate()

2.4. getAndUpdate()

This method works very similar as updateAndGet() but, it returns the old value of the key rather than updated one.


3. Monitor


The monitor class is regarded as the replacement of ReentrantLock also it is a bit more readable and less error-prone.


3.1. Monitor.newGuard()


Guava 21, added a new method – newGuard() – which return a Monitor.Guard instance, serves as a boolean condition for which a thread can wait:

Guava 21,增加了一个新的方法 – newGuard() – 它返回一个Monitor.Guard实例,作为线程可以等待的布尔条件。

public class MonitorExample {
    private List<String> students = new ArrayList<String>();
    private static final int MAX_SIZE = 100;

    private Monitor monitor = new Monitor();

    public void addToCourse(String item) throws InterruptedException {
        Monitor.Guard studentsBelowCapacity = monitor.newGuard(this::isStudentsCapacityUptoLimit);
        try {
        } finally {

    public Boolean isStudentsCapacityUptoLimit() {
        return students.size() > MAX_SIZE;

4. MoreExecutors


There are no additions in this class, but the sameThreadExecutor() API has been removed. This method was deprecated since v18.0 and it’s advised to use directExecutor() or newDirectExecutorService() instead.

这个类中没有新增内容,但是sameThreadExecutor() API已经被移除。这个方法从18.0版开始被废弃,建议使用directExecutor()newDirectExecutorService()代替。

5. ForwardingBlockingDeque


ForwardingBlockingDeque is an existing class which has been moved from common.collect because BlockingQueue is more of a concurrent collection type than a standard collection.


6. Conclusion


Guava 21 is not only trying to introduce new utilities to keep pace with Java 8, but also improving the existing model to be more meaningful.

Guava 21不仅试图引入新的实用程序以跟上Java 8的步伐,而且还在改进现有的模型以使其更有意义。

And as always, the code samples in this article are available in the GitHub repository.

和往常一样,本文中的代码样本可在GitHub 仓库中找到。