うさがにっき

読書感想文とプログラムのこと書いてきます

synchronized以外の同期処理

概要

synchronizedメソッド、ブロックを使えばスレッド間の同期処理が実現できる
しかし、手軽に利用できる反面メソッドを跨いだ同期処理や、簡単な演算処理でもオーバーヘッドが大きかったりする
そのため、今回はsynchronized以外の同期処理をまとめる

詳細

java.util.concurrent.locksパッケージによる明示的なロック

synchronizedがロックの獲得、解除を意識しなくて良い暗黙的なロックなのに対し、java.util.concurrent.locksはロックの獲得と解除を明示的に支持する必要がある明示的なロックと呼ぶ
使用例

        private int count;
        private final Lock lock = new ReentrantLock();
        
        public void countUp() {
            lock.lock();
            try {
                count++;
            }finally {
                lock.unlock();
            }
        }

注意するのはlockメソッドを呼び出した直後からtryブロックで括るようにすること
finally句で必ずunlockメソッドを呼び出すことを保証するため
ちなみに読み込みロックや、書き込みロックなど色々なことができるReentrantReadWriteLockクラスなどがある、詳細はjavadoc
java.util.concurrent.locks (Java Platform SE 6)

java.util.concurrent.atomicパッケージによる同期処理

ロックによって処理を同期させるのではなく、単一の変数に対する代入、取得をハードウェアレベルでatomicに実施する手段を提供している
つまり、演算中や取得中に他のスレッドに割り込まれることがなくなる
使用例

        private AtomicInteger count = new AtomicInteger();

        public void countUp() {
            count.getAndIncrement();
        }

詳細な使い方はjavadoc
java.util.concurrent.atomic (Java 2 Platform SE 5.0)

java.util.concurrent.atomicはマルチスレッド環境でのlong, double値を扱う場合にもよく使われる
32bit単位で読み書きを行うためatomic性を保持できないため
これは64bitVMでも同じ模様
java - Is writing a reference atomic on 64bit VMs - Stack Overflow

参考

AndroidエンジニアのためのモダンJava

AndroidエンジニアのためのモダンJava