Lockのサンプル

Javaの同期の基本はsynchronizedなのだけど、synchronizedはブロックとして使わないといけないので使いづらい場合がある。ロックの取得と開放を同じメソッド内で行わなくてはいけないし、異なるロックを自由なタイミングで取得開放できない。
そこで使うのがLockなのだけど、とりあえずsynchronizedと同じ使い方でのサンプル。
真ん中から向こうは一両の「電車」しか同時に進めません。


Lockの実装クラスとしては、ReentrantLockが用意されています。

Lock lock = new ReentrantLock();


lockメソッドでロックを取得。同時にひとつのスレッドしかロックを得ることはできません。

lock.lock();


lockの開放はunlockを使います。unlockはfinallyブロックに書くほうがよいです。ただ、同じブロックで単純にlock/unlockするならsynchronizedのほうがいいと思います。

}finally{
    lock.unlock();
}


ということでソース

import java.awt.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.*;

public class LockSample {
    private static Lock lock = new ReentrantLock();

    public static void main(String args[]) {
        JFrame f = new JFrame("Lockサンプル");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(0, 1));

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        f.setBounds((screenSize.width-400)/2, (screenSize.height-300)/2, 400, 300);

        for(int i = 0; i < 10; ++i){
            JTextField tf = new JTextField();
            f.add(tf);
            Runner r = new Runner();
            r.tf = tf;
            new Thread(r).start();
        }
        f.setVisible(true);
        
    }

    private static class Runner implements Runnable{
        JTextField tf;
        @Override
        public void run(){
            try {
                String tr = "電車>";
                for(int i = 0; i < 50; ++i){
                    tf.setText(tr);
                    tr = " " + tr;
                    Thread.sleep(50);
                }
                try{
                    lock.lock(); //ここから先は1つしか同時に進めない
                    for(int i = 0; i < 50; ++i){
                        tf.setText(tr);
                        tr = " " + tr;
                        Thread.sleep(50);
                    }
                }finally{
                    lock.unlock();
                }
            } catch (InterruptedException ex) {
            }
        }
    }

}