Thursday 13 December 2007

ThreadPool と格闘



http://mixi.jp/view_bbs.pl?id=25236109&comment_count=25&comm_id=954487

とかいう話があるので、Executors の例題と、PathFinder を扱ってみる。まぁ、なんとなくExecutorsの気持ちはわかりました。Thread と言うよりはタスクの投入と管理みたいにしたいわけね。

public class SimpleThreadExecutor {
  private final ExecutorService pool;
  public SimpleThreadExecutor(int poolSize) {
    pool = Executors.newFixedThreadPool(poolSize);
  }

  public void serve(int numThread) {
    for (int i = 1;i<= numThread;i++) {
     pool.execute(new SimpleThreadHandler("thread"+i));
    }
  }
  
  public static void main(String args[]) {
    int taskCount = 4;
    SimpleThreadExecutor e = new SimpleThreadExecutor(10);
    e.serve(taskCount);
    e.pool.shutdown();
    System.out.println("all done");
  }
}

だと思うんだけど、これが全然動いてくれません。いや、もちろん、Java PathFinderで動かす時なんだけど。

newFixedThreadPool は、 ThreadPoolExecutor を返すんだけど、こいつの状態が多すぎて、しかも、dead lock しちゃう。newCashedThreadPool だと、shutdown しないと止まらないし。この手のlibrary で shutdown() のdead lock を完全に避けるのは難しいんだよ。

Thread を作りながら順々に execute するあたりで、既に余計な状態組合せが増えているからなぁ。「性能を上げるために状態を増やす」ってのと、「ちゃんと動作することを確認するために、状態の見通しを良くする」ってのが相反しているわけだ。

なので、自分で状態の少ないThreadPool を作って実行することにしました。なんだけど、shutdown() のsemantics が良くわからない。

shutdown() Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

うーむ、意味不明です。orderly shutdown ってなんだ? Thread にはshutdown() なんてないしなぁ。stop() が使えないとするとjoin()かな。

そういえば、むらぼーも「java.util.concurrent のソースを見る」と言っていたなぁ。でも、昔は Java のソースを見るのはオープンソースな人にはタブーだった。今は、GPLになったから良いんだけど。

    public synchronized void shutdown() {
        for(Thread t:threadQueue) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        threadQueue.clear();
    }

とかにしたが、こんなものか?

しかし、学生向けの例題にはならないなぁ。

No comments: