- newCachedThreadPool 创建可缓存线程池
创建线程数量没有限制,可以灵活回收线程,如果设置线程空闲时间1分钟,则该工作线程自动终止,终止后提交了新任务,就会再重新建立一个线程。
缺点是在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。
核心线程数为0,非核心线程数为MAX_VALUE,
队列不存储值,总认为队列是满的,所以每次执行任务时都会创建非核心线程,非核心线程空闲了超过60秒(默认),就会自动回收。
2.newfixedThreadPool 创建定长的线程池
在达到长度之前,每提交一个任务都会创建一个线程,如果达到线程池最大数量,则提交到队列中,在空闲的时候也不会自动回收线程
核心线程数为参数传入,非核心线程数和核心线程数一样,
队列为无界队列,资源有限的时候容易引起OOM.
与newSingledThreadPool 不同的是核心线程数不为1.
3.newSingledThreadPool 创建单一线程执行。
只有一个线程按顺序执行任务,如果这个线程出现异常结束,会有另一个线程取代并按顺序执行。
corepoolsize 核心线程数为1 ,非核心线程数为1 ,
队列为无界队列,
单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
4.newScheduedThreadPool 创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。如果延迟3秒执行或每隔3秒执行一次
核心线程数为 参数设定,非核心线程数为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 = 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(Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newFixedPool(){
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newSingledPool(){
ExecutorService singledThreadPool = Executors.newSingleThreadExecutor();
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
singledThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(new Date()+"--"+Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newScheduledPool(){
ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
for (int i=0;i<10;i++){
final int index=i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduledThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(new Date()+"--"+Thread.currentThread().getName()+"==="+index);
}
});
}
}
@Test
public void newScheduledPool2() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println(new Date()+"--"+Thread.currentThread().getName()+"==="+"delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
}
@Test
public void newScheduledPool3() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
}
public static void main(String[] args) {
// ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
//
// scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
// public void run() {
// System.out.println("delay 1 seconds, and excute every 3 seconds");
//
// }
//
// }, 1, 3, TimeUnit.SECONDS);
ScheduledExecutorService scheduledThreadPool2 = Executors.newScheduledThreadPool(3);
scheduledThreadPool2.schedule(new Runnable() {
public void run() {
System.out.println(new Date()+"--"+Thread.currentThread().getName()+"==="+"delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
}
}
网友评论