Thread pool
http://www.javainthebox.net/laboratory/J2SE1.5/MiscAPI/ConcurrencyUtils/ConcurrencyUtils1.html
手っ取り早くやるなら
java.util.concurrent.Executors
を使う。
newCachedThreadPool newFixedThreadPool newScheduledThreadPool newSingleThreadExecutor
あたりのメソッドを使えばいい。
簡単なサンプル
1 |
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管理クラスを作る
1 |
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を呼んでも、スレッドがタスク実行中の場合はスレッドを停止しない。
[通知用URL]
Tweet
最終更新時間:2012年05月26日 23時45分33秒