携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
CallerRunsPolicy策略
CallerRunsPolicy策略是当任务添加到线程池中被拒绝时,会使用调用线程池的Thread线程对象处理被拒绝的任务。
执行代码如下:
public class FirstRunnable implements Runnable {
@Override
public void run() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
try {
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() +" 结束时间:"+simpleDateFormat.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行类执行代码如下:
@Slf4j
public class CallerRunsPolicyRun {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
FirstRunnable firstRunnable = new FirstRunnable();
LinkedBlockingDeque<Runnable> deque = new LinkedBlockingDeque<>(2);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 5, TimeUnit.SECONDS, deque, new ThreadPoolExecutor.CallerRunsPolicy());
log.info("线程名:{},开始执行时间:{}",Thread.currentThread().getName(),simpleDateFormat.format(new Date()));
for (int i = 0; i < 4 ; i++) {
threadPoolExecutor.submit(firstRunnable);
}
log.info("线程名:{},执行结束时间:{}",Thread.currentThread().getName(),simpleDateFormat.format(new Date()));
}
}
运行结果如下:
10:48:26.001 [main] INFO com.ozx.concurrentprogram.executor.controller.CallerRunsPolicyRun - 线程名:main,开始执行时间:10:48:25
10:48:26.061 [main] INFO com.ozx.concurrentprogram.executor.controller.CallerRunsPolicyRun - 线程名:main,执行结束时间:10:48:26
pool-1-thread-1 结束时间:10:48:31
pool-1-thread-2 结束时间:10:48:31
pool-1-thread-1 结束时间:10:48:36
pool-1-thread-2 结束时间:10:48:36
从运行结果看出,线程main被阻塞,严重影响程序的运行效率,所以并不建议这样做,可以通过改变的代码结果可以改善这种情况。
添加一个线程执行代码如下:
@Slf4j
public class SecondRunnable implements Runnable {
@Override
public void run() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
FirstRunnable firstRunnable = new FirstRunnable();
LinkedBlockingDeque<Runnable> deque = new LinkedBlockingDeque<>(2);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 5, TimeUnit.SECONDS, deque, new ThreadPoolExecutor.CallerRunsPolicy());
log.info("线程名:{},开始执行时间:{}",Thread.currentThread().getName(),simpleDateFormat.format(new Date()));
for (int i = 0; i < 4 ; i++) {
threadPoolExecutor.submit(firstRunnable);
}
log.info("线程名:{},执行结束时间:{}",Thread.currentThread().getName(),simpleDateFormat.format(new Date()));
}
}
运行类执行代码如下:
@Slf4j
public class CallerRunsPolicyRunn {
public static void main(String[] args) {
SecondRunnable secondRunnable = new SecondRunnable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(secondRunnable);
log.info("main主线程结束!");
}
}
运行结果如下:
11:26:04.921 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.SecondRunnable - 线程名:pool-1-thread-1,开始执行时间:11:26:04
11:26:04.919 [main] INFO com.ozx.concurrentprogram.executor.controller.CallerRunsPolicyRuunable - main主线程结束!
11:26:04.927 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.SecondRunnable - 线程名:pool-1-thread-1,执行结束时间:11:26:04
pool-2-thread-2 结束时间:11:26:09
pool-2-thread-1 结束时间:11:26:09
pool-2-thread-2 结束时间:11:26:14
pool-2-thread-1 结束时间:11:26:14
从运行结果看出线程main并未被阻塞。