スレッドプールのクラス構造
1.Executorは、トップレベルのインターフェースであり、実行する方法があります。
2.ExecutorServiceインタフェースは、スレッドを管理する方法を提供します。
3.AbstractExecutorService共通スレッド管理は、SchedulerExecutorServiceは、スケジュールされたタスクを管理します。
簡単な例
public class MyThread46 {
public static void main(String[] args)
{
long startTime = System.currentTimeMillis();
final List<Integer> l = new LinkedList<Integer>();
ThreadPoolExecutor tp = new ThreadPoolExecutor(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20000));
final Random random = new Random();
for (int i = 0; i < 20000; i++)
{
tp.execute(new Runnable()
{
public void run()
{
l.add(random.nextInt());
}
});
}
tp.shutdown();
try
{
tp.awaitTermination(1, TimeUnit.DAYS);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() - startTime);
System.out.println(l.size());
}
}
結果は以下のとおりであります
52
19919
ThreadPoolExecutor 7つのパラメータ
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
1.corePoolSize
存在できるスレッドの現在の数のスレッドプール
2.maximumPoolSizeの
スレッドの最大数を許可するようにスレッドプールを
3.keepAliveTimeの
スレッドの数がcorePoolSizeが終了したスレッドの前に、ほとんどの空き時間に動作しますよりも大きい場合。
4.unit
keepAliveTimeが時間単位の
5.workQueueの
タスクストアが未実行の
6.threadFactory
新しいスレッドを作成するときに使用するExecutorの工場を
7.handlerの
実行がブロックされたときに使用ハンドラを
maximumPoolSizeとCorePoolSize関係
1.プール内のスレッドの数がcorePoolSizeよりも少ない、新しいタスクがキューイングされているが、直接、新しいスレッドを追加します。
2以上corePoolSizeプール内のスレッドの数、完全なワークキューは、新しいタスクがワークキューを追加ではなく、新しいスレッドを追加しています。
3.プール以上corePoolSize、完全なワークキュー内のスレッドの数が、スレッドの数maximumPoolSizeよりも少ないが、タスクが追加された処理すべき新しいスレッドを追加します。
4.プール以上corePoolSize内のスレッドの数は、ワークキューが満杯であり、より等しいかmaximumPoolSizeより大きいスレッドの数は、新しいタスクが拒否され、ハンドラを使用して、処理タスクは拒否しました。
執行
1.newSingleThreadExecutos()シングルスレッドのスレッドプール
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
使用してキューに新しいタスク、ワークキューLinkedBlockingQueueアンバウンド形式のキュー
次のサンプルコードを
public class MyThread47{
static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
for(int i =0;i<10;i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
結果は以下のとおりであります
0
1
2
3
4
5
6
7
8
9
2.newFixedThreadPool(INTにnthreads)固定サイズのスレッドプール
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
固定サイズとシングルスレッドのスレッドプールスレッドプール同様に、スレッドの数を手動で指定することができ
、次のサンプルコードを
public class MyThread48 {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
結果は以下のとおりであります
0
1
2
3
4
5
6
8
7
9
3.newCachedThreadPool()アンバウンドスレッドプール
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
どのように多くの直接実行されるタスク、スレッドプールの最大数Integer.MAX_VALUEで、アイドル状態のスレッドの60年代自動回復。
次のサンプルコード
public class MyThread49 {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
}
}
}
結果は以下のとおりであります
0
1
2
3
4
5
6
7
8
9