美文网首页
Java线程池异常处理

Java线程池异常处理

作者: 明翼 | 来源:发表于2018-05-09 18:41 被阅读12次

    起因

    在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<Runnable> 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<Runnable> 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线程池异常处理

          本文链接:https://www.haomeiwen.com/subject/atdorftx.html