Thread&ThreadPoolExecutor异常处理

Thread异常处理
1. Thread外部Catch,捕获不到
public class NoCaughtThread
{
public static void main(String[] args)
{
try
{
Thread thread = new Thread(new Task());
thread.start();
}
catch (Exception e)//不会被catch
{
System.out.println("==Exception: "+e.getMessage());
}
}
}
class Task implements Runnable
{
@Override
public void run()
{
System.out.println(3/2);
System.out.println(3/0);
System.out.println(3/1);
}
}
2. Thread Run内部catch,可以捕获
public class InitiativeCaught
{
public void threadDeal(Runnable r, Throwable t)
{
System.out.println("==Exception: "+t.getMessage());
}
class InitialtiveThread implements Runnable
{
@Override
public void run()
{
Throwable thrown = null;
try
{
System.out.println(3/2);
System.out.println(3/0);
System.out.println(3/1);
}
catch(Throwable e)
{
thrown =e;
}
finally{
threadDeal(this,thrown);
}
}
}
public static void main(String[] args)
{
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new InitiativeCaught().new InitialtiveThread());
exec.shutdown();
}
}
3. 通过UncaughtExceptionHandler捕获异常
public class WitchCaughtThread
{
public static void main(String args[])
{
Thread thread = new Thread(new Task());
//为所有的Thread设置一个默认的UncaughtExceptionHandler
//Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler()); 给
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
}
}
class ExceptionHandler implements UncaughtExceptionHandler
{
@Override
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("==Exception: "+e.getMessage());
}
}
ThreadPoolExecutor线程池异常处理
1. UncaughtExceptionHandler在线程池中失效
public class ExecuteCaught
{
public static void main(String[] args)
{
ExecutorService exec = Executors.newCachedThreadPool();
Thread thread = new Thread(new Task());
//这样不管用
thread.setUncaughtExceptionHandler(new ExceptionHandler());
exec.execute(thread);
exec.shutdown();
}
}
2. 在run内部设置UncaughtExceptionHandler,只能用于executorService.execute,不能用于executorService.submit
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
//execute可以通过UncaughtExceptionHandler捕获
/*executorService.execute(new Runnable() {
@Override
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
int a = 1/0;
}
});*/
//submit 不能捕获
executorService.submit(new Runnable() {
@Override
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
int a = 1/0;
}
});
}
public static class CustomUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("eee:" + e);
}
}
2.1. 不能通过ThreadFactory 设置线程池UncaughtExceptionHandler
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
System.out.println("creating pooled thread");
final Thread thread = new Thread(r);
//以为这样可以抓住执行过程的异常
thread.setUncaughtExceptionHandler(exceptionHandler);
return thread;
}
};
ExecutorService threadPool = Executors.newFixedThreadPool(1, threadFactory);
3. executorService.submit要通过future.get来捕获异常
Future<?> submit = executorService.submit(new Runnable() {
@Override
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
int a = 1 / 0;
}
});
try {
Object o = submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("eee:" + e);//可以捕获
}
4. 重写ThreadPoolExecutor的afterExecute方法捕获异常
public class ThreadStudy2 {
public static class ExceptionCaughtThreadPool extends ThreadPoolExecutor {
List<Throwable> exceptions=new LinkedList();
public ExceptionCaughtThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
//构造函数省略
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (t!=null){
exceptions.add(t);
System.out.println("catch exception in afterExecute");
return;
}
System.out.println("everything is ok");
}
}
public static void main(String[] args){
ExceptionCaughtThreadPool threadPool=new ExceptionCaughtThreadPool(1,1,100,TimeUnit.SECONDS,new LinkedBlockingQueue<>());
threadPool.execute(new Runnable() {
@Override
public void run() {
throw new RuntimeException();
}
});
System.out.println("--------DONE-----------");
}
}
参考
Thread&ThreadPoolExecutor异常处理
Thread异常处理
1. Thread外部Catch,捕获不到
2. Thread Run内部catch,可以捕获
3. 通过UncaughtExceptionHandler捕获异常
ThreadPoolExecutor线程池异常处理
1. UncaughtExceptionHandler在线程池中失效
2. 在run内部设置UncaughtExceptionHandler,只能用于executorService.execute,不能用于executorService.submit
2.1. 不能通过ThreadFactory 设置线程池UncaughtExceptionHandler
3. executorService.submit要通过future.get来捕获异常
4. 重写ThreadPoolExecutor的afterExecute方法捕获异常
参考