独習Java第9章 マルチスレッドプログラミング(9.5 2回目)
前回やって意味が分からなかったので再度やってみることに。ただし全然わかってない気がする……
環境:MacOS 10.6.5 / Oracle(Sun) JDK6 update22
書いてみる
// Sync.java class Flag { public static boolean flag = true; } class IntBox { public synchronized void add(int value) { this._value += value; notify(); Flag.flag = true; } public synchronized int getValue() { return this._value; } private int _value = 0; } class ThreadEx extends Thread { ThreadEx(String name, IntBox intBox) { this._name = name; this._intBox = intBox; } public void run() { while (!Flag.flag) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Flag.flag = false; for (int i = 0; i < 50; i++) { this._intBox.add(1); System.out.println(this._name + ": " + this._intBox.getValue()); } } private String _name; private IntBox _intBox; } class Sync { public static void main(String args[]) { IntBox intbox = new IntBox(); Thread t[] = new ThreadEx[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { t[i] = new ThreadEx("t" + i, intbox); t[i].start(); } for (int i = 0; i < THREAD_COUNT; i++) { try { t[i].join(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("end"); } private final static int THREAD_COUNT = 50; }
睡魔と戦いつつJavaに毒づきながら書いたためひどいコードに。
実行してみる
$ javac Sync.java $ java Sync t0: 1 t0: 2 t0: 3 (略) t30: 2469 t30: 2477 t13: 2476 t30: 2478 t13: 2479 t13: 2480 (略) t13: 2498 t13: 2499 t13: 2500 end
t0〜t49まできれいに並んでくれないのは、JVMがそういう順番でスレッドを動かしてるからなのかな。
うーんと、要するにスレッドが動いていて、別のスレッドと競合(?)する可能性がある場合に何かしらのフラグでwait()して、触れるスレッドは触った後にnotify()を呼ぶことで衝突を回避できる…… ってことなのかな。
wait(), notify()は古いのでconcurrent使いましょう、とかいう記事を見たりとかしてもう半分どうでもよくなってきてるというのが正直なところ。
9章終わり。スレッドはもっと鍛えないとかなー……
それともスレッドを使うときはErlangとかScalaに逃げる…なんて。無理か。