サンタクロース問題を解く(Java)
サンタクロース問題をJavaで書いてみました(via サンタクロース問題を Squeak Smalltalk で)。Golfではありません。
…プログラムを書いてから問題を読み直したら、問題を読み違えてた(>_<)。こびとさんは10人いるのか。ふえーん。でもいいや、公開しちゃうもん。
import java.util.concurrent.*; import java.util.*; class Santa extends Thread { private static final int REINDEER_NUM = 9; private static final int ELF_NUM = 3; private boolean _readyAllElvesToWork = false; private boolean _readyAllReindeersToWork = false; private final CyclicBarrier _elfWorkBarrier = new CyclicBarrier(ELF_NUM, new Runnable() { public void run() { notifyAllElvesAreReadyToWork(); } }); private final CyclicBarrier _reindeerWorkBarrier = new CyclicBarrier(REINDEER_NUM, new Runnable() { public void run() { notifyAllReindeersAreReadyToWork(); } }); private final CyclicBarrier _elfPlayBarrier = new CyclicBarrier(ELF_NUM + 1); private final CyclicBarrier _reindeerPlayBarrier = new CyclicBarrier(REINDEER_NUM + 1); public static void main(String[] args) { new Santa().start(); } public void run() { startAllWorkers(); try { synchronized (this) { while (true) { while (!_readyAllElvesToWork && !_readyAllReindeersToWork) { wait(); } if (_readyAllReindeersToWork) { _readyAllReindeersToWork = false; _reindeerPlayBarrier.await(); } if (_readyAllElvesToWork) { _readyAllElvesToWork = false; _elfPlayBarrier.await(); } } } } catch (InterruptedException e) { } catch (BrokenBarrierException e) { } } private void startAllWorkers() { for (int i = 0; i < ELF_NUM; i++) { new Worker("Elf No." + i, _elfWorkBarrier, _elfPlayBarrier).start(); } for (int i = 0; i < REINDEER_NUM; i++) { new Worker("Reindeer No." + i, _reindeerWorkBarrier, _reindeerPlayBarrier).start(); } } private synchronized void notifyAllElvesAreReadyToWork() { System.out.println("All elves are ready to work!"); _readyAllElvesToWork = true; notifyAll(); } private synchronized void notifyAllReindeersAreReadyToWork() { System.out.println("All reindeers are ready to work!"); _readyAllReindeersToWork = true; notifyAll(); } } class Worker extends Thread { private static final Random _random = new Random(); private final CyclicBarrier _workBarrier; private final CyclicBarrier _playBarrier; public Worker(String name, CyclicBarrier workBarrier, CyclicBarrier playBarrier) { super(name); _workBarrier = workBarrier; _playBarrier = playBarrier; System.out.println(this + " is born."); } public void run() { try { while (true) { work(); play(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } private void work() throws InterruptedException, BrokenBarrierException { System.out.println(this + " is waiting to work."); _workBarrier.await(); randomSleep(); } private void play() throws InterruptedException, BrokenBarrierException { System.out.println(this + " is waiting to play."); _playBarrier.await(); randomSleep(); } public void randomSleep() throws InterruptedException { Thread.sleep(_random.nextInt(1000)); } }
- 書籍『増補改訂版Java言語で学ぶデザインパターン入門マルチスレッド編』もよろしく(^_^;