- 更清晰的业务名称
在普通日志和jstack输出时,带包含信息名称。通过线程名称,我们可以通容易确定正在进行的业务;反之,我们需要结合更多信息去判断。 - 各业务独立运行,互不影响
不同的业务相互独立,减低共用线程池可能带来的影响。
示例1:
假如有A、B两个业务,A业务耗时10s,B业务耗时10ms。使用不同线程池子,通过操作系统调度,虽然总的时间差不多,但A、B业务的执行时间与期望的时间都会比较接近;反之,当A业务将核心线程占满时,B线程执行完成的时间可能是期待的上百倍。
示例2:
若多个业务线程池完全独立,当一个业务出现故障时,比如出现死锁或意外的大任务,其他业务不受影响,只影响某一块业务而已;反之,影响范围会更大。 - 更好地定位线上的问题
当线程池出现故障时,通过线程池可以很快确定是哪块业务的问题。 - 避免存在嵌套调用出现的线程循环等待的问题
问题流程见上图,第2步提交的任务进入等待队列(第1步提交任务已将线程池的核心线程耗尽),则第4步拿不到返回结果,会出现第4步和第2步相互等待执行完,导致流程无法正常结束的问题。(业务A需要等业务B执行完成才能将线程还回线程池,但业务B又需要等业务A执行完才能有线程去执行)
public class NestedWaiting {
public static final ExecutorService executor = Executors.newFixedThreadPool(1);
public static void main(String[] args) {
executor.execute(() -> {
try {
doBiz1();
} catch (Throwable ignored) {
}
});
}
private static void doBiz1() throws ExecutionException, InterruptedException {
System.out.println("hello, biz1");
Future<String> biz2Result = executor.submit(() -> doBiz2());
System.out.println("hello" + biz2Result.get());
}
}