では、ReadWriteLockのサンプル。
読み込みスレッドは互いにロックせず、書き込みスレッドは他のスレッドとは同時に動かせない、というロックです。
サンプルでは、「か電車」が書き込みスレッド、「電車」が読み込みスレッドです。「か電車」が動くときには他のスレッドは動けません。
ReadWriteLockの実装としては、再入可能なReentrantReadWriteLockが用意されているので、これを使います。
ReadWriteLock lock = new ReentrantReadWriteLock();
実際にロックするときは、ReadWriteLockオブジェクトからwriteLock/readLockメソッドで書き込み用ロックか読み込み用ロックを取得します。
Lock reallock = writer ? lock.writeLock() : lock.readLock();
そうやって取得したロックを、通常のLockオブジェクトと同様にlock/unlockします。
reallock.lock(); reallock.unlock();
ということで、ソース
import java.awt.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.swing.*; public class ReadWriteLockSample { private static ReadWriteLock lock = new ReentrantReadWriteLock(); public static void main(String args[]) { JFrame f = new JFrame("ReadWriteLockサンプル"); 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; int speed = (int) (Math.random() * 100 + 50); boolean writer = Math.random() < .3; @Override public void run(){ try { String tr = (writer ? "か" : "") + "電車>"; for(int i = 0; i < 50; ++i){ tf.setText(tr); tr = " " + tr; Thread.sleep(speed); } Lock reallock = writer ? lock.writeLock() : lock.readLock(); try{ reallock.lock(); for(int i = 0; i < 50; ++i){ tf.setText(tr); tr = " " + tr; Thread.sleep(speed); } }finally{ reallock.unlock(); } } catch (InterruptedException ex) { } } } }