线程池的四种创建⽅式及区别
1. newCachedThreadPool 创建可缓存线程池
创建线程数量没有限制,可以灵活回收线程,如果设置线程空闲时间1分钟,则该⼯作线程⾃动终⽌,终⽌后提交了新任务,就会再重新建⽴⼀个线程。
缺点是在使⽤CachedThreadPool时,⼀定要注意控制任务的数量,否则,由于⼤量线程同时运⾏,很有会造成系统瘫痪。
核⼼线程数为0,⾮核⼼线程数为MAX_VALUE,
队列不存储值,总认为队列是满的,所以每次执⾏任务时都会创建⾮核⼼线程,⾮核⼼线程空闲了超过60秒(默认),就会⾃动回收。
在达到长度之前,每提交⼀个任务都会创建⼀个线程,如果达到线程池最⼤数量,则提交到队列中,在空闲的时候也不会⾃动回收线程
核⼼线程数为参数传⼊,⾮核⼼线程数和核⼼线程数⼀样,
队列为⽆界队列,资源有限的时候容易引起OOM.
与newSingledThreadPool 不同的是核⼼线程数不为1.
只有⼀个线程按顺序执⾏任务,如果这个线程出现异常结束,会有另⼀个线程取代并按顺序执⾏。
corepoolsize 核⼼线程数为1 ,⾮核⼼线程数为1 ,
队列为⽆界队列,
单⼯作线程最⼤的特点是可保证顺序地执⾏各个任务,并且在任意给定的时间不会有多个线程是活动的。
核⼼线程数为 参数设定,⾮核⼼线程数为MAX_VALUE
定义了⼀个DelayedWorkQueue,它是⼀个有序队列,会通过每个任务按照距离下次执⾏时间间隔的
⼤⼩来排序;
线程池执⾏逻辑说明:
判断核⼼线程数是否已满,核⼼线程数⼤⼩和corePoolSize参数有关,未满则创建线程执⾏任务
若核⼼线程池已满,判断队列是否满,队列是否满和workQueue参数有关,若未满则加⼊队列中
若队列已满,判断线程池是否已满,线程池是否已满和maximumPoolSize参数有关,若未满创建线程执⾏任务
若线程池已满,则采⽤拒绝策略处理⽆法执执⾏的任务,拒绝策略和handler参数有关
拒绝策略
拒绝策略 => 默认采⽤的是AbortPolicy拒绝策略,直接在程序中抛出RejectedExecutionException异常【因为是运⾏时异常,不强制catch】,这种处理⽅式不够优雅。处理拒绝策略有以下⼏种⽐较推荐:
在程序中捕获RejectedExecutionException异常,在捕获异常中对任务进⾏处理。针对默认拒绝策略
使⽤CallerRunsPolicy拒绝策略,该策略会将任务交给调⽤execute的线程执⾏【⼀般为主线程】,此
时主线程将在⼀段时间内不能提交任何任务,从⽽使⼯作线程处理正在执⾏的任务。此时提交的线程将被保存在TCP队列中,TCP队列满将会影响客户端,这是⼀种平缓的性能降低
⾃定义拒绝策略,只需要实现RejectedExecutionHandler接⼝即可
如果任务不是特别重要,使⽤DiscardPolicy和DiscardOldestPolicy拒绝策略将任务丢弃也是可以
public class ThreadTest {
@Test
public void newCachedPool(){
ExecutorService cachedThreadPool = wCachedThreadPool();
for (int i=0;i<10;i++){
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@Override
public void run() {
java线程池创建的四种
System.out.println(Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newFixedPool(){
ExecutorService fixedThreadPool = wFixedThreadPool(3);
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newSingledPool(){
ExecutorService singledThreadPool = wSingleThreadExecutor();
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@Override
public void run() {
System.out.println(new Date()+"--"+Thread.currentThread().getName()+"==="+index);            }
});
}
}
@Test
public void newScheduledPool(){
ExecutorService scheduledThreadPool = wScheduledThreadPool(2);
for (int i=0;i<10;i++){
final int index=i;
try {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。