
线程池的任务中,会出现一种特殊的异常。在结果上没有输出,但是程序不会抛出报错,这就需要我们对这种异常进行处理。我们先从通过一个实例来分析这种异常的情况,然后为大家带来处理线程池异常的两种方法及代码实例部分。接下来我们看看线程池发生异常的原理和解决办法吧。
1.异常情况
1 2 3 4 5 6 7 8 | 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方法上增加异常处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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 = null ;
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处理未捕获异常
1 2 3 4 5 6 7 8 9 10 11 | 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线程池异常的处理方法,在理解了发生这种异常的原理后,我们进一步针对这种情况提出两种解决方法,学会后赶紧尝试着去解决吧。