型アノテーションと、その活用例としてのChecker Frameworkを6回に渡って紹介してきました。今回は、その最終回です。

 前回、Checker Frameworkのチェッカを紹介しましたが、今回はその続きです。今回は、Lock Checkerを紹介します。また、後半では、リフレクションで型アノテーションを扱う手法について紹介します。

Lock Checker

 マルチスレッドのアプリケーションの開発は多くの落とし穴があります。最も基本的なのは、複数のスレッドから同時に変数にアクセスしてはいけない点です。そして、同時にアクセスを行わせないためには、同期化しなくてはいけません。

 同期化するためには以下の2種類の方法を使用します。

  • synchronized
  • java.util.concurrent.lock.Lockインタフェース

 古典的なのがsynchronizedを使用した手法です。LockインタフェースはJ2SE 5で導入されたConcurrent Utilitiesに含まれています。Lockインタフェースの実装クラスとしては、再入可能なロックであるReentrantLockクラス、悲観的ロックをサポートしたStampedLockクラスなどがあります。

 例えば、リスト1はsynchronizedを使用した同期化の例です。

リスト1●synchronizedメソッドの使用例

private List<String> list = new ArrayList<>();

public synchronized void add(String text) {
    list.add(text);
}

public synchronized String get(int index) {
    return list.get(index);
}

 メソッドにsynchronziedを付加することにより、メソッドが複数のスレッドから同時にアクセスすることを禁止します。なお、リスト1はリスト2と同じ意味になります。

リスト2●synchronizedブロックの使用例

private List<String> list = new ArrayList<>();

public void add(String text) {
    synchronized (this) {
        list.add(text);
    }
}

public String get(int index) {
    synchronized (this) {
        return list.get(index);
    }
}

 synchrnozedブロックの丸カッコに指定するオブジェクトはロックオブジェクトと呼ばれています。リスト2では自分自身をロックオブジェクトとして扱っています。変数listから見た場合、ロックオブジェクトによってガードされているということができます。