Новое в Guava 21 common.util.concurrent

Новое в Guava 21 common.util.concurrent

1. Вступление

Вprevious article мы начали изучать новые функции, представленные в пакетеcommon.collect.

В этой быстрой статье давайте рассмотрим дополнения к пакетуcommon.util.concurrent.

2. AtomicLongMap

В параллельных сценариях стандартныйHashMap может не очень хорошо работать, так как он просто не является параллельным. В этом конкретном сценарииAtomicLongMap спасает вас, сохраняя значенияLong потокобезопасным способом.

AtomicLongMap был введен очень давно в Guava 11. Теперь были добавлены четыре новых метода.

2.1. НакопитьAndGet ()

МетодaccumulateAndGet() обновляет значение, связанное с ключом, объединяя его с существующим значением с помощью функции аккумулятора. Затем он возвращает обновленное значение:

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

Этот метод имеет аналогичную функциональность, как определено выше, но он возвращает старое значение вместо обновленного значения (как предполагает порядок операций в том же самом).

2.3. updateAndGet ()

МетодupdateAndGet() обновляет текущее значение ключа, используя указанную функцию, указанную в качестве второго параметра. Затем он возвращает обновленное значение ключа:

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

Этот метод работает очень похоже наupdateAndGet(), но возвращает старое значение ключа, а не обновленное.

3. монитор

Класс монитора рассматривается как заменаReentrantLock, также он немного более читабелен и менее подвержен ошибкам.

3.1. Monitor.newGuard()

В Guava 21 добавлен новый метод -newGuard(), который возвращает экземплярMonitor.Guard, служит логическим условием, которого поток может ждать:

public class MonitorExample {
    private List students = new ArrayList();
    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. Подробнее

В этом классе нет дополнений, но APIsameThreadExecutor() был удален. Этот метод устарел, начиная с версии 18.0, и вместо него рекомендуется использоватьdirectExecutor() илиnewDirectExecutorService().

5. ForwardingBlockingDeque

ForwardingBlockingDeque - это существующий класс, который был перемещен изcommon.collect, посколькуBlockingQueue является скорее параллельным типом коллекции, чем стандартной коллекцией.

6. Заключение

Guava 21 не только пытается представить новые утилиты, чтобы идти в ногу с Java 8, но также улучшает существующую модель, чтобы сделать ее более значимой.

И, как всегда, образцы кода в этой статье доступны вGitHub repository.