Guava 21 中Concurrent的新功能
Contents
1. 简介
在上一篇文章 中,我们开始探索common.collect包中引入的新功能。
在这篇快速文章中,让我们来看看 common.util.concurrent包的新增内容。
2. AtomicLongMap
在并发场景中,标准HashMap可能无法很好地工作,因为它根本不是并发的。在这种特殊情况下,AtomicLongMap通过以线程安全的方式存储Long值来帮助您。
AtomicLongMap很久以前在 Guava 11 中引入。现在,添加了四个新方法。
2.1. accumulatorAndGet()
*accumulatorAndGet()*方法通过使用累加器函数将其与现有值合并来更新与键链接的值。然后,它返回更新后的值:
@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. updateAndGet()
此方法的工作方式与*updateAndGet()*非常相似,但它返回键的旧值而不是更新后的值。
3. Monitor
监视器类被视为ReentrantLock的替代品,它更具可读性且不易出错。
3.1. Monitor.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. MoreExecutors
这个类中没有添加,但相同的ThreadExecutor() API 已被删除。此方法自 v18.0 起已弃用,建议改用directExecutor()或newDirectExecutorService()。
5. ForwardingBlockingDeque
ForwardingBlockingDeque是一个现有的类,它已从common.collect移出,因为BlockingQueue更像是一种并发集合类型而不是标准集合。