スレッドプールテクノロジーの使用
1.スレッドプールを作成します(使用されません)
ExecutorServiceのthreadPool1 = Executors.newFixedThreadPool(3); // 固定サイズ
ExecutorServiceのthreadPool2 = Executors.newCachedThreadPool(); //弾性伸縮スレッドプール、強い、強い場合ExecutorServiceのthreadPool3 = Executors.newSingleThreadExecutor(); //唯一
れますこの方法で作成されたスレッドプールには欠点があります(Aliの元の言葉)
1)FixedThreadPoolおよびSingleThreadPool:
許可されるリクエストキューの長さはInteger.MAX_VALUEであり、大量のリクエストが蓄積されてOOMになる可能性があります。
2)CachedThreadPoolおよびScheduledThreadPool:
許可される作成スレッドの数はInteger.MAX_VALUEであり、これにより多数のスレッドが作成され、OOMが発生する可能性があります。
基本的な作成方法は同じです。
Executors.newFixedThreadPool(3)底层为:
return new **ThreadPoolExecutor**(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
Executors.newCachedThreadPool()底层为:
return new **ThreadPoolExecutor**(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
Executors.newSingleThreadExecutor()底层为:
new **ThreadPoolExecutor**(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())
LinkedBlockingQueueはサイズを指定しません。デフォルトは最大の整数です。
2.推奨される作成方法(推奨)
//現在のコンピュータまたはサーバーのスレッド番号を取得します
public class ThreadPoolTec {
public static void main(String[] args) {
//推荐的线程池的创建方法
/**
* 最多可以存在的人,maximumPoolSize + LinkedBlockingDeque的容量
*触发非活跃线程变为活跃的方法是:当前任务数量大于最大线程池容量,每超一个则激活一个,直到都被激活
* // 拒绝策略说明:
* // 1. AbortPolicy (默认的:队列满了,就丢弃任务抛出异常!)
* // 2. CallerRunsPolicy(哪来的回哪去? 谁叫你来的,你就去哪里处理)
* // 3. DiscardOldestPolicy (尝试将最早进入对立与的人任务删除,尝试加入队列)
* // 4. DiscardPolicy (队列满了任务也会丢弃,不抛出异常)
*/
Integer processors = Runtime.getRuntime().availableProcessors());
ExecutorService threadPool = new ThreadPoolExecutor(
2,//核心活跃线程数,类比银行两个柜台一直保持营业
processors ,//线程池最大大小,类比银行共5个柜台可以营业
2L,//超时回收空闲的线程,类比有三个非活跃线程处于活跃状态,在一定时间还未接到任务就进入非活跃状态(就是不营业了)
TimeUnit.SECONDS,//时间单位
new LinkedBlockingDeque<>(3),//存放等待任务的队列,类比为银行的候客区,不指定大小的话就是最大整数
Executors.defaultThreadFactory(),// 线程工厂,不修改!用来创建
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略,即候客区满了,不再允许其他人排队了
);
try {
for(int j=1;j<=8;j++){
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"is running………………");
});
}
} catch (Exception e) {
e.printStackTrace();
}finally {
threadPool.shutdown();
}
}
}
いくつかの注意事項を
次に示します。1.スレッドプールを作成するスレッドの最大数は、マシンを実行しているスレッドの数がリソースの最大使用率であるのと同じです。
Runtime.getRuntime()。AvailableProcessors());は、現在のマシンのスレッドの最大数を取得し
ます2.タスクキューのキューは、サイズ、新しいLinkedBlockingDeque <>(3)を指定する必要があります。
3.判断戦略は特定の要件に依存します。新しいThreadPoolExecutor.CallerRunsPolicy()を使用します
。4.ラムダで記述されたマルチスレッドの実行に注意してください:
for(int j = 1; j <= 8; j ++){
threadPool.execute (()-> {
System.out.println(Thread.currentThread().GetName()+ "is running ..................");
});
}
動作原理の基礎となるThreadPoolExecutor:
拒否戦略のフローチャート: