Java线程池异常处理

起因

在Java默认的线程池中执行的程序,如果程序产生异常导致线程池里面的线程死掉,完全没有任何信息抛出来,这个是个很可怕的事情,程序静默,从日志看不到任何有用信息。

解决办法

线程池一般有两种提交办法:通过execute和submit两种方式往线程池提交我们的任务。

  1. 如果是execute 这种可以通过继承线程池,然后处理:
  
import java.util.concurrent.BlockingQueue;  
import java.util.concurrent.ThreadPoolExecutor;  
import java.util.concurrent.TimeUnit;  
  
public class MyThreadPoolExecutor extends ThreadPoolExecutor {  
  
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,  
            long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {  
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);  
    }  
  
    @Override  
    protected void afterExecute(Runnable r, Throwable t) {  
        super.afterExecute(r, t);  
        System.out.println("MyThreadPoolExecutor.afterExecute()");  
        if (t != null) {
            System.out.println("Error msg:{}",t.getMessage());  
        }
    }  
  
}  

2)如果是submit方式提交:

protected void afterExecute(Runnable r, Throwable t) {  
    super.afterExecute(r, t);  
    Future f = (Future) r;  
    try {  
        f.get();  
    } catch (InterruptedException e) {  
        logger.error("线程池中发现异常,被中断", e);  
    } catch (ExecutionException e) {  
        logger.error("线程池中发现异常,被中断", e);  
    }  
  
}  

总结

最终采用如下的代码,可能不高效,但是异常都可以捕获到。

package threads;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyThreadExcutor extends ThreadPoolExecutor {

    private static final Logger logger = LoggerFactory.getLogger(MyThreadExcutor.class);

    public MyThreadExcutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
            BlockingQueue workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);

    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if (t != null) {
            logger.error("Find exception error reason :{}", t.getMessage());
        }

        Future f = (Future) r;
        try {
            f.get();
        } catch (InterruptedException e) {
            logger.error("线程池中发现异常,被中断", e);
        } catch (ExecutionException e) {
            logger.error("线程池中发现异常,被中断", e);
        }

    }
}

你可能感兴趣的:(Java线程池异常处理)