线程池执行异常不打印日志
public class ThreadPoolTest { private static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(500), new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("submit-execute-test"); return thread; } } ); private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS"); public static void main(String[] args) { Random random = new Random(); for (int i = 0; i < 10; i++) { int j = i; executor.execute(new Runnable() { @Override public void run() { try { TimeUnit.SECONDS.sleep(2 + random.nextInt(5)); } catch (InterruptedException e) { e.printStackTrace(); } if (j % 2 != 0) { throw new RuntimeException("线程错误"); } LinkedBlockingQueue<Runnable> queue = (LinkedBlockingQueue) executor.getQueue(); System.out.println(formatter.format(LocalDateTime.now()) + "::" + Thread.currentThread().getName() + "::" + "核心线程数 :" + executor.getCorePoolSize() + "::最大线程数 :" + executor.getMaximumPoolSize() + "::活动线程数 :" + executor.getActiveCount() + "::任务完成数" + executor.getCompletedTaskCount() + "::队列使用 :" + queue.size() + "::队列未使用 :" + queue.remainingCapacity() + "::队列总共大小 :" + (queue.size() + queue.remainingCapacity())); } }); } } }
从打印中可以看到当execute提交runable的时候异常会输出。
2、我们将execute 换成submit ,其他都不变,再次查看运行情况
可以看出除了我们在代码里面输出内容并未抛出异常。
public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; }
newTaskFor 方法是创建FutureTask 对象,那么具体不抛异常应该就在FutureTask的run方法了。
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); }
FutureTask 的run方法,在run方法中对Throwable 异常进行捕获,错误的时候将异常设置到返回结果。执行正常结束,将返回结果set到结果中
public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; //设置异常到返回结构中 setException(ex); } //执行正确结束设置返回结果 if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }