Javaスレッドプールの実装
スレッドプールの役割:
スレッドプールの役割は、システムで実行されるスレッドの数を制限することです.
システムの環境状況に応じて、スレッドの数を自動的にまたは手動で設定し、実行の最適な効果を達成することができます.スレッドが少なくなるとシステムリソースが浪費され、多くなるとシステムの混雑効率が低下します.スレッドプールでスレッド数を制御し、他のスレッドが待機するようにします.1つのタスクの実行が完了し、キューから先頭のタスクを取り出して実行を開始します.キューにタスク待機プロセスがない場合、スレッドプールのスレッドは待機します.新しいタスクが実行される必要がある場合、スレッドプールに待機している作業スレッドがあれば、実行を開始できます.そうでなければ待機キューに入ります.
スレッドプールを使用する理由:
スレッドの作成と破棄の回数を減らし、各作業スレッドを再利用し、複数のタスクを実行できます.また、システムの耐性に応じて、スレッドプール内のワークラインスレッドの数を調整し、メモリの消費が多すぎるため、サーバを疲れさせないようにすることもできます(スレッドごとに約1 MBのメモリが必要で、スレッドが開くほど、消費されるメモリが大きくなり、最後にハングアップします).
スレッドプールクラス
テストクラス
原文住所:http://sunnylocus.iteye.com/blog/223327
スレッドプールの役割は、システムで実行されるスレッドの数を制限することです.
システムの環境状況に応じて、スレッドの数を自動的にまたは手動で設定し、実行の最適な効果を達成することができます.スレッドが少なくなるとシステムリソースが浪費され、多くなるとシステムの混雑効率が低下します.スレッドプールでスレッド数を制御し、他のスレッドが待機するようにします.1つのタスクの実行が完了し、キューから先頭のタスクを取り出して実行を開始します.キューにタスク待機プロセスがない場合、スレッドプールのスレッドは待機します.新しいタスクが実行される必要がある場合、スレッドプールに待機している作業スレッドがあれば、実行を開始できます.そうでなければ待機キューに入ります.
スレッドプールを使用する理由:
スレッドの作成と破棄の回数を減らし、各作業スレッドを再利用し、複数のタスクを実行できます.また、システムの耐性に応じて、スレッドプール内のワークラインスレッドの数を調整し、メモリの消費が多すぎるため、サーバを疲れさせないようにすることもできます(スレッドごとに約1 MBのメモリが必要で、スレッドが開くほど、消費されるメモリが大きくなり、最後にハングアップします).
スレッドプールクラス
import java.util.LinkedList;
public class ThreadPool extends ThreadGroup {
private boolean isClosed = false; //
private LinkedList workQueue; //
private static int threadPoolID = 1; // id
public ThreadPool(int poolSize) { //poolSize
super(threadPoolID + ""); // ThreadGroup
setDaemon(true); // ,
workQueue = new LinkedList(); //
for(int i = 0; i < poolSize; i++) {
new WorkThread(i).start(); // ,
}
}
/** , */
public synchronized void execute(Runnable task) {
if(isClosed) {
throw new IllegalStateException();
}
if(task != null) {
workQueue.add(task);//
notify(); // getTask()
}
}
/** , */
private synchronized Runnable getTask(int threadid) throws InterruptedException {
while(workQueue.size() == 0) {
if(isClosed) return null;
System.out.println(" "+threadid+" ...");
wait(); // ,
}
System.out.println(" "+threadid+" ...");
return (Runnable) workQueue.removeFirst(); // ,
}
/** */
public synchronized void closePool() {
if(! isClosed) {
waitFinish(); //
isClosed = true;
workQueue.clear(); //
interrupt(); // , ThreadGroup
}
}
/** */
public void waitFinish() {
synchronized (this) {
isClosed = true;
notifyAll(); // getTask()
}
Thread[] threads = new Thread[activeCount()]; //activeCount() 。
int count = enumerate(threads); //enumerate() ThreadGroup ,
for(int i =0; i < count; i++) { //
try {
threads[i].join(); //
}catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* , , ,
*/
private class WorkThread extends Thread {
private int id;
public WorkThread(int id) {
// , ThreadPool
super(ThreadPool.this,id+"");
this.id =id;
}
public void run() {
while(! isInterrupted()) { //isInterrupted() Thread ,
Runnable task = null;
try {
task = getTask(id); //
}catch(InterruptedException ex) {
ex.printStackTrace();
}
// getTask() null getTask() ,
if(task == null) return;
try {
task.run(); //
}catch(Throwable t) {
t.printStackTrace();
}
}// end while
}// end run
}// end workThread
}
テストクラス
public class ThreadPoolTest {
public static void main(String[] args) throws InterruptedException {
ThreadPool threadPool = new ThreadPool(3); // 3
Thread.sleep(500); // 500 ,
//
for (int i = 0; i <=5 ; i++) { // 6
threadPool.execute(createTask(i));
}
threadPool.waitFinish(); //
threadPool.closePool(); //
}
private static Runnable createTask(final int taskID) {
return new Runnable() {
public void run() {
System.out.println("Task" + taskID + " ");
System.out.println("Hello world");
System.out.println("Task" + taskID + " ");
}
};
}
}
原文住所:http://sunnylocus.iteye.com/blog/223327