1. Введение
В предыдущей статье мы начали изучать новый функционал, представленный в пакете common.collect
.
В этой быстрой статье давайте рассмотрим дополнения к пакету common.util.concurrent
.
2. Атомная длинная карта
В параллельных сценариях стандартный HashMap
может работать не очень хорошо, поскольку он просто не является параллельным. В этом конкретном сценарии AtomicLongMap
выручает вас, сохраняя значения Long
потокобезопасным способом.
AtomicLongMap
был представлен давным-давно в Guava 11. Теперь было добавлено четыре новых метода.
2.1. аккумулировать и получить ()
Метод accumulationAndGet()
обновляет значение, связанное с ключом, объединяя его с существующим значением с помощью функции аккумулятора. Затем он возвращает обновленное значение:
@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. получить и накапливать ()
Этот метод имеет аналогичную функциональность, как определено выше, но он возвращает старое значение вместо обновленного значения (как предполагает порядок операций в том же).
2.3. обновить и получить ()
Метод 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. получить и обновить ()
Этот метод работает очень похоже на updateAndGet()
, но возвращает старое значение ключа, а не обновленное.
3. Монитор
Класс монитора считается заменой ReentrantLock,
кроме того, он немного более удобочитаем и менее подвержен ошибкам.
3.1. Монитор.newGuard()
В 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);
monitor.enterWhen(studentsBelowCapacity);
try {
students.add(item);
} finally {
monitor.leave();
}
}
public Boolean isStudentsCapacityUptoLimit() {
return students.size() > MAX_SIZE;
}
}
4. Больше исполнителей
В этом классе нет дополнений, но API sameThreadExecutor()
удален. Этот метод устарел, начиная с версии 18.0, и вместо него рекомендуется использовать directExecutor()
или newDirectExecutorService()
.
5. ForwardingBlockingDeque
ForwardingBlockingDeque
— это существующий класс, который был перемещен из common.collect,
поскольку BlockingQueue
больше похож на параллельный тип коллекции, чем на стандартную коллекцию.
6. Заключение
Guava 21 не только пытается представить новые утилиты, чтобы идти в ногу с Java 8, но и улучшить существующую модель, чтобы сделать ее более значимой.
И как всегда примеры кода в этой статье доступны в репозитории GitHub .