JDK 1.5のスレッド池(java.util.co ncurrent.ThreadPool Exector)使用概要


マルチスレッドマスターDugg Leaの貢献の下で、JDK 1.5には合併特性に対する多くのサポートが加わりました。例えば、スレッド池。
一、紹介スレッド池類はjava.util.co ncurrent.ThreadPool Exectorで、よく使われる構造方法は:ThreadPool Exector(int coreadPool Exector、int maximPool Size、long keep Alive Time、TimeUnit、BlockingQue<Runnable>Qworkeweet Que、Execedl。
corePoolSize:スレッド池メンテナンススレッドの最小数maximPoolSize:スレッド池メンテナンススレッドの最大数keep Alive Time:スレッド池メンテナンススレッドで許可されている空き時間unit:スレッド池メンテナンススレッドで許可されている空き時間の単位workQue:スレッド池で使用されているバッファキューhander:スレッド池による拒否タスクの処理ポリシーをexecで実行します。ute(Runnable)メソッドがスレッド池に追加され、タスクはRunnableタイプのオブジェクトであり、タスクの実行方法はRunnableタイプのオブジェクトのrun()メソッドである。タスクがexecuteによってスレッドプールに追加しようとした場合:ここで、スレッドプールの数がcorePoolSize以下であれば、スレッドプールのスレッドが空き状態であっても、新たなスレッドを作成して、追加されたタスクを処理します。
この時点でスレッド池の数がcorePoolSizeに等しいが、バッファキューのworkQueが満杯でない場合、バッファキューにジョブが入れられます。
この時スレッドの池の数がcorePoolSizeより大きい場合、バッファキューがworkQueでいっぱいになり、スレッドの池の数がmaximPoolSizeより小さい場合、新たなスレッドを立てて追加されたジョブを処理します。
この時スレッドの池の数がcorePoolSizeより大きい場合、バッファキューのworkQueがいっぱいになり、スレッドの池の数がmaximPoolSizeに等しい場合、handlerによって指定されたポリシーでこのタスクを処理します。すなわち、処理タスクの優先度は、コアスレッドcorePoolSize、タスクキューworkQue、最大スレッドmaximPoolSizeであり、3つが満杯になったら、handlerを使って拒否されたタスクを処理することである。スレッド池中のスレッド数がcorePoolSizeより大きい場合、あるスレッドの空き時間がkeep Alive Timeを超えると、スレッドは終了されます。このように、スレッド池は、プール内のスレッド数を動的に調整することができる。unitオプションのパラメータは、java.util.co ncurrent.TimeUnitのいくつかの静的属性です。NANOSECONDS、MICROSTONSDS、MILLISECONS、SECONDS。workQue私がよく使うのは、java.util.co ncurrent.ArayBlocking Quehandlerの4つの選択があります。ThreadPool Exector.AbortPolicy()java.util.co ncurrent.RejectExecution Exceptionの異常ThreadPool Exector.rancer.Ctronの追加タスクです。彼は自動的にexecute()メソッドThreadPool Exector.DiscrdOldest Policy()古いタスクを捨ててThreadPool Exector.DiscrdPolicy()を呼び出します。
二、一般的な用法例
//------------------------------------------------------------
//TestThreadPool.java
//package cn.simplelife.exercise;

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {

private static int produceTaskSleepTime = 2;
private static int consumeTaskSleepTime = 2000;
private static int produceTaskMaxNumber = 10;

public static void main(String[] args) {

//       
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());

for(int i=1;i<=produceTaskMaxNumber;i++){
try {
//      ,         
String task = "task@ " + i;
System.out.println("put " + task);
threadPool.execute(new ThreadPoolTask(task));

//    ,      
Thread.sleep(produceTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
 
/**
*         
* @author hdpan
*/
public static class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = 0;
//          
private Object threadPoolTaskData;

ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}
public void run(){
//      ,           ,         
System.out.println("start .."+threadPoolTaskData);
try {
////    ,      
Thread.sleep(consumeTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
}
//------------------------------------------------------------
 
説明:
1、このプログラムでは、一つのタスクはRunnableタイプのオブジェクト、つまりThreadPoolTaskタイプのオブジェクトです。
2、一般的にタスクは処理方式の他に処理が必要なデータがあり、処理したデータは構造方法によりタスクに転送されます。
3、このプログラムの中で、main()の方法は残忍な指導者に相当して、彼は多くの任務を派遣して、threadPoolという任劳恨むグループになくしてやります。
このチームの中に少なくとも二人の選手がいます。彼らが忙しくて来られないなら、任務は任務リストに入れられます。
たまっているミッションが多すぎて、リストに入れられない(3つ以上)場合は、新しいメンバーを雇って手伝います。しかし、コストを考慮して、多すぎる隊員を雇えなくて、せいぜい4人しか雇えません。
もし4人の選手が忙しい時、また新しい任務があると、このグループは処理できなくなります。任務は一つの策略を通じて処理されます。へへ
メンバーの仕事にはコストが必要です。仕事が暇だったら、3 SECONDSまで新しい仕事がないと、解雇される選手もいます。しかし、グループの正常運行のために、いくら仕事が暇でも、チームのメンバーは2人を下回ってはいけません。
4、produceTask SleepTimeとconsumeTaskSleepTimeのサイズを調整することにより、配信タスクと処理タスクの速度の制御を実現し、これらの2つの値を変更すると、異なる速度でのプログラムの動作状況を観察することができる。
5、4の中で指すデータを調整することによって、タスクの廃棄戦略を調整し、他の3つの戦略に切り替えることによって、異なる戦略下の異なる処理方式が見られます。
6、他の使用方法については、jdkの助けを参照してください。分かりやすく、使いやすいです。