线程池的任务中,会出现一种特殊的异常。在结果上没有输出,但是程序不会抛出报错,这就需要我们对这种异常进行处理。我们先从通过一个实例来分析这种异常的情况,然后为大家带来处理线程池异常的两种方法及代码实例部分。接下来我们看看线程池发生异常的原理和解决办法吧。
1.异常情况
ExecutorService threadPool = Executors.newFixedThreadPool(5); for (int i = 0; i < 5; i++) { threadPool.submit(() -> { System.out.println("current thread name" + Thread.currentThread().getName()); Object object = null; System.out.print("result## "+object.toString()); }); }
虽然没有结果输出,但是没有抛出异常,所以我们无法感知任务出现了异常。
2.异常处理方法
(1)在run方法上增加异常处理
public class FutureTask<V> implements RunnableFuture<V> { ... 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); } } public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s); } private V report(int s) throws ExecutionException { Object x = outcome; if (s == NORMAL) return (V)x; if (s >= CANCELLED) throw new CancellationException(); throw new ExecutionException((Throwable)x); } }
(2)使用UncaughtExceptionHandler处理未捕获异常
Thread thread = new Thread(() -> { System.err.println(3 / 2); System.err.println(3 / 0); }); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.err.println(Thread.currentThread().getName() + "==>" + e.getMessage()); } }); thread.start();
以上就是java线程池异常的处理方法,在理解了发生这种异常的原理后,我们进一步针对这种情况提出两种解决方法,学会后赶紧尝试着去解决吧。