Java: サンタクロース問題
http://karetta.jp/article/blog/oneline/030756
これはJavaでも解いておかないとと思った。メモリ共有型マルチスレッドといったら、Javaだよね。
import java.util.*; public class Santa { static volatile boolean running = true; static ArrayList<Worker> forReindeer = new ArrayList<Worker>(9); static LinkedList<Worker> forElf = new LinkedList<Worker>(); static class Worker extends Thread { final List<Worker> queue; final String name; Worker (String n, List<Worker> o){ this.name = n; this.queue = o;} public void run () { while (running){ try{ sleep((long)Math.ceil(Math.random()*1000)); System.out.println(name + " comes."); synchronized(queue){ queue.add(this);} synchronized(this){ this.wait();} }catch(InterruptedException e){} } } } public static void main (String args[]) { Worker[] reindeers = new Worker[9]; Worker[] elves = new Worker[10]; for (int i=0; i<reindeers.length; ++i) reindeers[i] = new Worker("Raindeer_" + (i+1), forReindeer); for (int i=0; i<elves.length; ++i) elves[i] = new Worker("Elf_" + (i+1), forElf); for (Worker r: reindeers) r.start(); for (Worker e: elves) e.start(); int count = 0; try{ while (count<10){ Thread.sleep(10); boolean flg = false; synchronized (forReindeer){ flg = forReindeer.size() >= 9; } if (flg){ deliver(); ++count; continue;} synchronized (forElf){ flg = forElf.size() >= 3; } if (flg){ meeting(); ++count; continue;} } }catch(InterruptedException e){} running = false; for (Worker r: reindeers) r.interrupt(); for (Worker e: elves) e.interrupt(); } static void deliver() throws InterruptedException { System.out.println("Delivery..."); Thread.sleep((long)Math.ceil(Math.random()*1000)); synchronized (forReindeer){ for (Worker r: forReindeer){ System.out.println(r.name + " returns."); synchronized(r){ r.notify();} } forReindeer.clear(); } } static void meeting() throws InterruptedException { System.out.println("Meeting..."); Thread.sleep((long)Math.ceil(Math.random()*1000)); synchronized (forElf){ for (int i=0; i<3; ++i){ Worker e = forElf.remove(0); System.out.println(e.name + " returns."); synchronized(e){ e.notify();} } } } }