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.

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:

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

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

    assertEquals(totalNotesRequired, oldValue * noOfStudents);
}

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()

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:

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

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

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:

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);
        monitor.enterWhen(studentsBelowCapacity);
        try {
            students.add(item);
        } finally {
            monitor.leave();
        }
    }

    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.

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.

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