ということで、バージョンアップ

もろもろ修正。各問題ごとの出力は、解き終わった後に一気に出すことに。途中でデバッグ出力が欲しければ、それはそれぞれでSystem.errあたりに出せばよいということで。
後、やはりMainのstatic変数は邪魔でしかないので、すべてTaskSplitter(旧TaskPool)クラスに全部押し込めてしまった。普通に問題を解く上では絶対に使わないと思われるので。必要なものに関しては、先にloadしてあるので問題ないだろう。

あ、ちなみにこれですが、勝手に使ってもらってもOKですが、教えてくれると嬉しいです。使い心地なんかも併せて教えてくれると、修正するかもしれません。

import java.util.*;
import java.math.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Main{
  public Myout myout;
  public void solve(int problem_number){
    this.myout = Myout.get(problem_number);
    Scanner sc = TaskSplitter.sc;
    Lock lock = TaskSplitter.lock;
    //read phase
    
    //read ends
    lock.unlock();
    //execution start
    
  }
  public static void main(String  argv){
    //long t1 = System.currentTimeMillis();
    Scanner sc = new Scanner(System.in);
    TaskSplitter.sc = sc;
    int n = sc.nextInt();
    TaskSplitter.tasksize = n;
    Thread  threads = new Thread[TaskSplitter.NUM_THREADS];
    for(int i = 0; i < TaskSplitter.NUM_THREADS; i++){
      threads[i] = new Thread(new TaskSplitter());
      threads[i].start();
    }
    for(int i = 0; i < TaskSplitter.NUM_THREADS; i++){
      try{
        threads[i].join();
      }catch(InterruptedException e){
        System.err.println(e);
      }
    }  
    Myout.flush();
    //long t2 = System.currentTimeMillis();
    //System.err.println(((double)t2 - t1) / 1000.);
  }
}

class TaskSplitter implements Runnable{
  public final static int NUM_THREADS = 4;
  public static int tasksize;
  public static int now = 0;
  static Scanner sc;
  public static ReentrantLock lock;
  static{
    lock = new ReentrantLock();
  }
  public void run(){
    while(true){
      lock.lock();
      if(now >= tasksize)
        break;
      //exec
      int problem_num = now;
      now++;
      Main main = new Main();
      main.solve(problem_num);
      main.myout.ins_flush();
    }
    lock.unlock(); // important
  }
}



class Myout implements Comparable{
  public int num;
  private String str;
  private static LinkedList list;
  static{
    list = new LinkedList();
  }
  private Myout(int problem_number){
    this.num = problem_number;
    this.str = "";
  }
  public static Myout get(int problem_number){
    Myout out = new Myout(problem_number);
    list.add(out);
    return out;
  }
  public void print(boolean x){
    printMain("" + x);
  }
  public void print(char x){
    printMain("" + x);
  }
  public void print(char x){
    printMain("" + x);
  }
  public void print(double x){
    printMain("" + x);
  }
  public void print(float x){
    printMain("" + x);
  }
  public void print(int x){
    printMain("" + x);
  }
  public void print(long x){
    printMain("" + x);
  }
  public void print(Object x){
    printMain("" + x);
  }
  public void println(){
    printlnMain("");
  }
  public void println(boolean x){
    printlnMain("" + x);
  }
  public void println(char x){
    printlnMain("" + x);
  }
  public void println(char x){
    printlnMain("" + x);
  }
  public void println(double x){
    printlnMain("" + x);
  }
  public void println(float x){
    printlnMain("" + x);
  }
  public void println(int x){
    printlnMain("" + x);
  }
  public void println(long x){
    printlnMain("" + x);
  }
  public void println(Object x){
    printlnMain("" + x);
  }
  private void printMain(String str){
    this.str = this.str + str;
  }
  private void printlnMain(String str){
    this.str = this.str + str + "\n";
  }
  public void printf(String format, Object... args){
    String f = String.format(format, args);
    this.str = this.str + f;
  }
  
  public void ins_flush(){
    System.err.printf("Case #%d: " + this.str, this.num + 1);
  }
  public static void flush(){
    Collections.sort(list);
    for(Myout m: list){
      System.out.printf("Case #%d: " + m.str, m.num + 1);
    }
  }
  public int compareTo(Myout m){
    return this.num - m.num;
  }
}