jdk1.5提供スレッドプール
マルチスレッドマスターDoug Leaの貢献でJDK 1.5には、スレッドプールなどの同時プロパティのサポートが多数追加されています.
一、紹介
スレッドプールクラスはjavaです.util.concurrent.ThreadPoolExecutor、一般的な構造方法は次のとおりです.
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue workQueue,
RejectedExecutionHandler handler)
CorePoolSize:スレッドプールメンテナンススレッドの最小数
maximumPoolSize:スレッドプールメンテナンススレッドの最大数
keepAliveTime:スレッドプールメンテナンススレッドによって許可されるアイドル時間
unit:スレッドプールメンテナンススレッドが許可するアイドル時間の単位
workQueue:スレッドプールで使用されるバッファキュー
handler:スレッドプールによるタスク拒否の処理ポリシー
1つのタスクはexecute(Runnable)メソッドによってスレッドプールに追加され、タスクはRunnableタイプのオブジェクトであり、タスクの実行方法はRunnableタイプのオブジェクトのrun()メソッドである.
タスクをexecute(Runnable)メソッドでスレッドプールに追加する場合:
スレッドプールの数がcorePoolSizeより小さい場合は、スレッドプールのスレッドがアイドル状態であっても、追加されたタスクを処理するために新しいスレッドを作成します.
スレッドプールの数がcorePoolSizeに等しいが、バッファキューworkQueueが満たされていない場合、タスクはバッファキューに格納されます.
このとき、スレッドプールの数がcorePoolSizeより大きい場合、バッファキューworkQueueがいっぱいで、スレッドプールの数がmaximumPoolSizeより小さい場合は、追加されたタスクを処理するために新しいスレッドを作成します.
スレッドプールの数がcorePoolSizeより大きく、バッファキューworkQueueがいっぱいで、スレッドプールの数がmaximumPoolSizeに等しい場合は、handlerが指定したポリシーによってこのタスクを処理します.
つまり、タスクの優先順位は次のとおりです.
コアスレッドcorePoolSize、タスクキューworkQueue、最大スレッドmaximumPoolSizeの3つが満たされている場合は、拒否されたタスクをhandlerで処理します.
スレッドプール内のスレッド数がcorePoolSizeより大きい場合、あるスレッドのアイドル時間がkeepAliveTimeを超えると、スレッドは終了します.これにより、スレッドプールは、プール内のスレッド数を動的に調整することができる.
unitオプションのパラメータはjavaです.util.concurrent.TimeUnitの静的プロパティ:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS.
私がよく使うのはjavaです.util.concurrent.ArrayBlockingQueue
handlerには4つの選択肢があります.
ThreadPoolExecutor.AbortPolicy()
javaを投げ出すutil.concurrent.RejectedExecutionException異常
ThreadPoolExecutor.CallerRunsPolicy()
現在のタスクを追加し直すと、execute()メソッドが自動的に繰り返し呼び出されます.
ThreadPoolExecutor.DiscardOldestPolicy()
古い任務を捨てる
ThreadPoolExecutor.DiscardPolicy()
当面の任務を投げ捨てる
二、一般用法例
//------------------------------------------------------------
//------------------------------------------------------------
説明:
1、このプログラムでは、1つのタスクはRunnableタイプのオブジェクト、つまりThreadPoolTaskタイプのオブジェクトです.
2、一般的にタスクは処理方式のほかに、処理するデータが必要であり、処理するデータは構造方法によってタスクに伝達される.
3、このプログラムの中で、main()の方法は残忍な指導者に相当して、彼は多くの任務を派遣して、threadPoolという任労任怨のグループに捨ててやります.
このグループには少なくとも2人の選手がいて、もし彼ら2人が忙しくて来られないならば、任務は任務リストに入れられます.
溜まったクエストが多すぎて、クエストリストに入れられない(3個を超える)ほど多い場合は、新しい隊員を雇って手伝います.しかし、コストを考慮すると、多くの隊員を雇うことはできず、せいぜい4人しか雇うことができない.
もし4人の隊員がすべて忙しい時、更に新しい任務があれば、このグループは処理できなくて、任務は1種の策略を通じて処理されて、私達の処理方式は絶えず配布して、この任務を受け入れるまで(更に残忍です!ほほほ).
メンバーの仕事にはコストがかかるので、仕事が暇で、3 SECONDSまで暇で新しい任務がないと、解雇されるメンバーもいますが、グループの正常な運営のために、いくら仕事が暇でも、グループのメンバーは2人以上ではありません.
4、produceTaskSleepTimeとconsumeTaskSleepTimeのサイズを調整することで、配布タスクと処理タスクの速度の制御を実現し、この2つの値を変更することで、異なるレートでのプログラムの動作状況を観察することができる.
5、4に示すデータを調整し、さらにタスク破棄ポリシーを調整し、他の3つのポリシーに置き換えることで、異なるポリシーの下での異なる処理方式を見ることができます.
6、その他の使用方法については、jdkの助けを参照して、理解しやすく使用します.
一、紹介
スレッドプールクラスはjavaです.util.concurrent.ThreadPoolExecutor、一般的な構造方法は次のとおりです.
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue
RejectedExecutionHandler handler)
CorePoolSize:スレッドプールメンテナンススレッドの最小数
maximumPoolSize:スレッドプールメンテナンススレッドの最大数
keepAliveTime:スレッドプールメンテナンススレッドによって許可されるアイドル時間
unit:スレッドプールメンテナンススレッドが許可するアイドル時間の単位
workQueue:スレッドプールで使用されるバッファキュー
handler:スレッドプールによるタスク拒否の処理ポリシー
1つのタスクはexecute(Runnable)メソッドによってスレッドプールに追加され、タスクはRunnableタイプのオブジェクトであり、タスクの実行方法はRunnableタイプのオブジェクトのrun()メソッドである.
タスクをexecute(Runnable)メソッドでスレッドプールに追加する場合:
スレッドプールの数がcorePoolSizeより小さい場合は、スレッドプールのスレッドがアイドル状態であっても、追加されたタスクを処理するために新しいスレッドを作成します.
スレッドプールの数がcorePoolSizeに等しいが、バッファキューworkQueueが満たされていない場合、タスクはバッファキューに格納されます.
このとき、スレッドプールの数がcorePoolSizeより大きい場合、バッファキューworkQueueがいっぱいで、スレッドプールの数がmaximumPoolSizeより小さい場合は、追加されたタスクを処理するために新しいスレッドを作成します.
スレッドプールの数がcorePoolSizeより大きく、バッファキューworkQueueがいっぱいで、スレッドプールの数がmaximumPoolSizeに等しい場合は、handlerが指定したポリシーによってこのタスクを処理します.
つまり、タスクの優先順位は次のとおりです.
コアスレッドcorePoolSize、タスクキューworkQueue、最大スレッドmaximumPoolSizeの3つが満たされている場合は、拒否されたタスクをhandlerで処理します.
スレッドプール内のスレッド数がcorePoolSizeより大きい場合、あるスレッドのアイドル時間がkeepAliveTimeを超えると、スレッドは終了します.これにより、スレッドプールは、プール内のスレッド数を動的に調整することができる.
unitオプションのパラメータはjavaです.util.concurrent.TimeUnitの静的プロパティ:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS.
私がよく使うのはjavaです.util.concurrent.ArrayBlockingQueue
handlerには4つの選択肢があります.
ThreadPoolExecutor.AbortPolicy()
javaを投げ出すutil.concurrent.RejectedExecutionException異常
ThreadPoolExecutor.CallerRunsPolicy()
現在のタスクを追加し直すと、execute()メソッドが自動的に繰り返し呼び出されます.
ThreadPoolExecutor.DiscardOldestPolicy()
古い任務を捨てる
ThreadPoolExecutor.DiscardPolicy()
当面の任務を投げ捨てる
二、一般用法例
//------------------------------------------------------------
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、このプログラムでは、1つのタスクはRunnableタイプのオブジェクト、つまりThreadPoolTaskタイプのオブジェクトです.
2、一般的にタスクは処理方式のほかに、処理するデータが必要であり、処理するデータは構造方法によってタスクに伝達される.
3、このプログラムの中で、main()の方法は残忍な指導者に相当して、彼は多くの任務を派遣して、threadPoolという任労任怨のグループに捨ててやります.
このグループには少なくとも2人の選手がいて、もし彼ら2人が忙しくて来られないならば、任務は任務リストに入れられます.
溜まったクエストが多すぎて、クエストリストに入れられない(3個を超える)ほど多い場合は、新しい隊員を雇って手伝います.しかし、コストを考慮すると、多くの隊員を雇うことはできず、せいぜい4人しか雇うことができない.
もし4人の隊員がすべて忙しい時、更に新しい任務があれば、このグループは処理できなくて、任務は1種の策略を通じて処理されて、私達の処理方式は絶えず配布して、この任務を受け入れるまで(更に残忍です!ほほほ).
メンバーの仕事にはコストがかかるので、仕事が暇で、3 SECONDSまで暇で新しい任務がないと、解雇されるメンバーもいますが、グループの正常な運営のために、いくら仕事が暇でも、グループのメンバーは2人以上ではありません.
4、produceTaskSleepTimeとconsumeTaskSleepTimeのサイズを調整することで、配布タスクと処理タスクの速度の制御を実現し、この2つの値を変更することで、異なるレートでのプログラムの動作状況を観察することができる.
5、4に示すデータを調整し、さらにタスク破棄ポリシーを調整し、他の3つのポリシーに置き換えることで、異なるポリシーの下での異なる処理方式を見ることができます.
6、その他の使用方法については、jdkの助けを参照して、理解しやすく使用します.