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();}
      }
    }
  }
}