トップ 一覧 置換 検索 ヘルプ RSS ログイン

Java で Thread をまとめて管理するの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!Thread pool
http://www.javainthebox.net/laboratory/J2SE1.5/MiscAPI/ConcurrencyUtils/ConcurrencyUtils1.html

手っ取り早くやるなら
 java.util.concurrent.Executors 
を使う。
 newCachedThreadPool
 newFixedThreadPool
 newScheduledThreadPool
 newSingleThreadExecutor
あたりのメソッドを使えばいい。

!!簡単なサンプル
{{code Java,
import java.util.concurrent.*;

public class test {
  public static void main(String[] args){
    ExecutorService service = Executors.newFixedThreadPool(5);
    testTask task = new testTask();
    
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    service.execute(task);
    
    service.shutdown();
  }
  
  static class testTask implements Runnable {
    public void run(){
      System.out.println(Thread.currentThread());
      try {
        Thread.sleep(1000);
      } catch (Exception e){
      }
    }
  }
}
}}
shutdown は別スレッドで
 ThreadPoolExecutor#getActiveCount() 
が 0 になるのを監視したりするの良いかも。


!!!独自にThread管理クラスを作る
{{code Java,
import java.util.*;

public class ThreadManager {
  private int threadNum = 1;
  private byte[] lock = new byte[0]; 
  private LinkedList<Runnable> tasks;
  private boolean isStopAll = false;
  private ArrayList<Runnable> threadList;
  private int activeThread = 0;
  
  
  public ThreadManager(){
    threadNum = 1;
    activeThread = 0;
    tasks = new LinkedList<Runnable>();
    isStopAll = false;
    threadList = new ArrayList<Runnable>();
  }
  
  public ThreadManager(int threadNum){
    this();
    this.threadNum = threadNum;
  }
  
  public void startAll(){
    this.activeThread = threadNum;
    for (int i = 0; i < threadNum; i++){
      threadList.add(new Task(this));
    }
  }
  
  public void addTask(Runnable runnable){
    synchronized(lock){
      tasks.add(runnable);
      lock.notify();
      // lock.notifyAll();
      System.out.println(Thread.currentThread() + " add notiry tasks=" + tasks.size());
    }
  }
  
  public Runnable pollTask(){
    synchronized(lock){
      while(tasks.size() == 0) {
        activeThread--;
        
        if (isStopAll && activeThread == 0){
          System.out.println("stop!!!");
          lock.notifyAll();
          return null;
        }
        
        try {
          System.out.println(Thread.currentThread() + " wait");
          lock.wait();
          System.out.println(Thread.currentThread() + " wait break");
        } catch (Exception e){}
        activeThread++;
      }
      System.out.println(Thread.currentThread() + " poll tasks=" + tasks.size());
      return tasks.poll();
    }
  }
  
  public void stopAll(){
    synchronized(lock){
      isStopAll = true;
      lock.notifyAll();
    }
  }
  
  public int getActiveCount(){
    synchronized(lock){
      return activeThread;
    }
  }
  
  static class Task extends Thread{
    private ThreadManager manager;
    
    public Task(ThreadManager manager){
      this.manager = manager;
      start();
    }
    
    public void run(){
      while(true){
        Runnable runnable = manager.pollTask();
        if (runnable == null){
          break;
        }
        // manager.activeThread();
        runnable.run();
      }
    }
  }
}

public class test {
  public static void main(String[] args){
    ThreadManager manager = new ThreadManager(5);
    
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    manager.startAll();
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    manager.stopAll();
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    manager.addTask(new testRunnable(manager));
    
  }
  
  
  static class testRunnable implements Runnable {
    ThreadManager manager;
    
    public testRunnable(ThreadManager manager){
      this.manager = manager;
    }
    
    public void run(){
      try {
      Thread.sleep(1000);
      } catch (Exception e){
      }
      System.out.println(Thread.currentThread());
      if ( ((int)(Math.random() * 10)) % 2 == 0){
        manager.addTask(new testRunnable(manager));
      }
    }
  }
}
}}

以下の2つの条件を満たさないと、スレッドを停止しない様になっている
* stopAll を呼ぶ
* 全てのスレッドがタスクを終えている
stopAllを呼んでも、スレッドがタスク実行中の場合はスレッドを停止しない。

{{category2 プログラミング言語,Java}}