携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
自定义拒绝策略RejectedExecutionHandler接口的使用
自定义拒绝策略类代码如下:
@Slf4j
public class TheRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.info("线程名:{} 被拒绝",((FutureTask)r).toString());
}
}
线程执行代码如下:
@Slf4j
public class TheRunnable implements Runnable {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public TheRunnable(String username){
super();
this.username=username;
}
@Override
public void run() {
log.info("线程名:{} 在运行",username);
}
}
运行类代码如下:
public class RejectedExecutionHandlerRun {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
threadPoolExecutor.setRejectedExecutionHandler(new TheRejectedExecutionHandler());
threadPoolExecutor.submit(new TheRunnable("G1"));
threadPoolExecutor.submit(new TheRunnable("G2"));
threadPoolExecutor.submit(new TheRunnable("G3"));
threadPoolExecutor.shutdown();
threadPoolExecutor.submit(new TheRunnable("G4"));
}
}
运行结果如下:
15:05:34.037 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.TheRunnable - 线程名:G1 在运行 15:05:34.037 [pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.service.TheRunnable - 线程名:G2 在运行 15:05:34.037 [pool-1-thread-3] INFO com.ozx.concurrentprogram.executor.service.TheRunnable - 线程名:G3 在运行 15:05:34.037 [main] INFO com.ozx.concurrentprogram.executor.handler.TheRejectedExecutionHandler - 线程名:java.util.concurrent.FutureTask@553f17c 被拒绝
从运行结果看出线程池调用自定义拒绝策略,接口RejectedExecutionHandler的主要作用是当线程池关闭后依然有任务要执行时,可以实现一些处理。
方法execute()与submit()的区别
execute()与submit()的区别如下:
- 方法execute()没有返回值,而submit()方法可以有返回值。
- 方法execute()在默认情况下异常直接抛出,不能捕获,但可以通过自定义ThreadFactory的方式进行捕获,而submit()方法在默认的情况下,可以catch Execution Exception 捕获异常。
-
关于有无返回值
运行类代码如下:
@Slf4j public class ExecuteOrSubmitRun { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); threadPoolExecutor.execute(new Runnable() { @Override public void run() { log.info("线程池执行了execute()方法,Runnable没有返回值!"); } }); Future<String> future = threadPoolExecutor.submit(new Callable<String>() { @Override public String call() throws Exception { log.info("线程池执行了submit()方法,Callable有返回值!"); return String.valueOf(System.currentTimeMillis()); } }); try { log.info("Callable返回值:{}",future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }运行结果如下:
15:32:33.528 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.ExecuteOrSubmitRun - 线程池执行了execute()方法,Runnable没有返回值!
15:32:33.573 [pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.controller.ExecuteOrSubmitRun - 线程池执行了submit()方法,Callable有返回值!
15:32:33.573 [main] INFO com.ozx.concurrentprogram.executor.controller.ExecuteOrSubmitRun - Callable返回值:1659943953573
从运行结果看出,execute()没有返回值,而submit()方法具有返回值的功能。