afterExecute进行异常处理,但是注意! 这个也只适用于excute提交,因为submit的task.run里面把异常吞了
点击查看代码
final void runWorker(Worker w) {
//当前线程
Thread wt = Thread.currentThread();
//我们的提交的任务
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
//直接就调用了task的run方法
task.run(); //如果是futuretask的run,里面是吞掉了异常,不会有异常抛出,
// 因此Throwable thrown = null; 也不会进入到catch里面
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
//调用线程池的afterExecute方法 传入了task和异常
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
FutureTask 执行记录异常在 outcome,通过future.get()可以把异常读出来
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
验证 submit 吞了异常
public static void main(String[] args) {
Thread t = new Thread(() -> {
int a = 0;
int b = 1;
System.out.println("begin");
int c = b / a; // divide by zero
System.out.println("end");
});
t.setUncaughtExceptionHandler((t1, e) -> {
System.out.println("Thread.setUncaughtExceptionHandler\t" + e); // 不生效,因为 submit(t) 接收的是Runnable对象,最终jdk会把 Runnable 包装为 Thread 执行。外部传入一个 Thread 对象虽然设置了 setUncaughtExceptionHandler,不起作用
});
ExecutorService a = pool();
a.submit(t); // submit 不会抛出异常
}
public static ExecutorService pool() {
// 创建线程池
final int corePoolSize = 2;
final int maximumPoolSize = 64;
final long keepAliveTime = 60L;
TimeUnit timeUnit = TimeUnit.SECONDS;
BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pool")
// .setUncaughtExceptionHandler(
// (t1, e) ->{
// System.out.println("ThreadFactory.setUncaughtExceptionHandler\t"+e);
// }
// )
.build();
RejectedExecutionHandler rejectedExecutionHandler = (r, executor) -> {
System.out.println("abort");
};
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue,
threadFactory, rejectedExecutionHandler){
// @Override
// protected void afterExecute(Runnable r, Throwable t) {
// super.afterExecute(r, t);
// System.out.println("afterExecute\t"+t);
// }
};
}
输出:
begin
execute 提交
public static void main(String[] args) {
Thread t = new Thread(() -> {
int a = 0;
int b = 1;
System.out.println("begin");
int c = b / a; // divide by zero
System.out.println("end");
});
t.setUncaughtExceptionHandler((t1, e) -> {
System.out.println("Thread.setUncaughtExceptionHandler\t" + e);
});
ExecutorService a = pool();
a.execute(t);
}
public static ExecutorService pool() {
// 创建线程池
final int corePoolSize = 2;
final int maximumPoolSize = 64;
final long keepAliveTime = 60L;
TimeUnit timeUnit = TimeUnit.SECONDS;
BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pool")
// .setUncaughtExceptionHandler(
// (t1, e) ->{
// System.out.println("ThreadFactory.setUncaughtExceptionHandler\t"+e);
// }
// )
.build();
RejectedExecutionHandler rejectedExecutionHandler = (r, executor) -> {
System.out.println("abort");
};
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue,
threadFactory, rejectedExecutionHandler){
// @Override
// protected void afterExecute(Runnable r, Throwable t) {
// super.afterExecute(r, t);
// System.out.println("afterExecute\t"+t);
// }
};
}
输出:
begin
Exception in thread "pool" java.lang.ArithmeticException: / by zero
at com.huawei.wim.app.service.ZipTest.lambda$main\(0(ZipTest.java:56) at java.lang.Thread.run(Thread.java:748) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor\)Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
异常顺序
使用了 afterExecute,还是可以爆出异常
public static void main(String[] args) {
Runnable t = () -> {
int a = 0;
int b = 1;
System.out.println("begin");
int c = b / a; // divide by zero
System.out.println("end");
};
ExecutorService a = pool();
a.execute(t);
}
public static ExecutorService pool() {
// 创建线程池
final int corePoolSize = 2;
final int maximumPoolSize = 64;
final long keepAliveTime = 60L;
TimeUnit timeUnit = TimeUnit.SECONDS;
BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pool")
// .setUncaughtExceptionHandler(
// (t1, e) ->{
// System.out.println("ThreadFactory.setUncaughtExceptionHandler\t"+e);
// }
// )
.build();
RejectedExecutionHandler rejectedExecutionHandler = (r, executor) -> {
System.out.println("abort");
};
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue,
threadFactory, rejectedExecutionHandler){
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
System.out.println("afterExecute\t"+t);
}
};
}
输出:
begin
afterExecute java.lang.ArithmeticException: / by zero
Exception in thread "pool" java.lang.ArithmeticException: / by zero
at com.huawei.wim.app.service.ZipTest.lambda$main\(0(ZipTest.java:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor\)Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
afterExecute + setUncatchExeceptionHandler
public static void main(String[] args) {
Runnable t = () -> {
int a = 0;
int b = 1;
System.out.println("begin");
int c = b / a; // divide by zero
System.out.println("end");
};
ExecutorService a = pool();
a.execute(t);
}
public static ExecutorService pool() {
// 创建线程池
final int corePoolSize = 2;
final int maximumPoolSize = 64;
final long keepAliveTime = 60L;
TimeUnit timeUnit = TimeUnit.SECONDS;
BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pool")
.setUncaughtExceptionHandler(
(t1, e) ->{
System.out.println("ThreadFactory.setUncaughtExceptionHandler\t"+e);
}
)
.build();
RejectedExecutionHandler rejectedExecutionHandler = (r, executor) -> {
System.out.println("abort");
};
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, blockingQueue,
threadFactory, rejectedExecutionHandler){
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
System.out.println("afterExecute\t"+t);
}
};
}
输出:
begin
afterExecute java.lang.ArithmeticException: / by zero
ThreadFactory.setUncaughtExceptionHandler java.lang.ArithmeticException: / by zero