Guava 21の新機能common.util.concurrent

Guava 21の新機能common.util.concurrent

1. 前書き

previous articleでは、common.collectパッケージで導入された新機能の調査を開始しました。

この簡単な記事では、common.util.concurrentパッケージへの追加について説明します。

2. AtomicLongMap

並行シナリオでは、標準のHashMapは単に並行ではないため、実際にはうまく機能しない可能性があります。 この特定のシナリオでは、AtomicLongMapは、スレッドセーフな方法でLong値を格納することによってあなたを救済します。

AtomicLongMapはずっと前にGuava11で導入されました。 現在、4つの新しいメソッドが追加されています。

2.1. AccumulateAndGet()

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()メソッドは、2番目のパラメーターとして提供された指定された関数を使用して、キーの現在の値を更新します。 次に、更新されたキーの値を返します。

@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は、Monitor.Guardインスタンスを返す新しいメソッドnewGuard()を追加しました。これは、スレッドが待機できるブール条件として機能します。

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. MoreExecutors

このクラスには追加はありませんが、sameThreadExecutor()APIは削除されています。 このメソッドはv18.0以降非推奨になり、代わりにdirectExecutor()またはnewDirectExecutorService()を使用することをお勧めします。

5. ForwardingBlockingDeque

ForwardingBlockingDequeは、BlockingQueueが標準コレクションよりも並行コレクションタイプであるため、common.collectから移動された既存のクラスです。

6. 結論

Guava 21は、Java 8に対応するために新しいユーティリティを導入しようとしているだけでなく、既存のモデルをより意味のあるものに改良しています。

そしていつものように、この記事のコードサンプルはGitHub repositoryで利用できます。