【问题标题】:How to avoid thread in threadpool dead when exception thrown without try catch如何在没有尝试捕获的情况下抛出异常时避免线程池中的线程死亡
【发布时间】:2018-08-26 22:19:20
【问题描述】:

我的代码如下所示:

public class ExceptionTest {
    public static Logger log = LoggerFactory.getLogger(ExceptionTest.class);
    public final static ThreadFactory factory = new ThreadFactory() {
        @Override
        public Thread newThread(Runnable target) {
            final Thread thread = new Thread(target);
            log.debug("Creating new worker thread");
            thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread t, Throwable e) {
                    log.error("Uncaught Exception", e);
                }
            });
            return thread;
        }

    };
    final static ExecutorService executor = Executors.newCachedThreadPool(factory);
    public static void main(String[] args) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println(Thread.currentThread().getName());
                    int i = 1;
                    int j = 0;
                    System.out.println(i / j);
                }
            }
        });
    }

}

控制台只打印一次消息。这意味着线程已经死亡。有没有其他方法可以防止线程死亡(try catch 块除外,这是很多重复的代码)。

【问题讨论】:

    标签: java multithreading exception-handling threadpool


    【解决方案1】:

    不,如果不使用try...catch 块,您将无法实现这一点,请参阅jls

    如果找不到可以处理异常的 catch 子句,则 当前线程(遇到异常的线程)是 终止。


    而且,我认为缓存线程池中线程的终止不是问题,因为下次提交新任务时,将创建一个新线程来处理它。


    如果真的很重要,并且你不想重复代码,你可以写一个这样的包装类:

    public class WrapperRunnable implements Runnable {
    
        Runnable runnable;
    
        public WrapperRunnable(Runnable runnable) {
            this.runnable = runnable;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    runnable.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    并将WrapperRunnable提交给执行者:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
            int i = 1;
            int j = 0;
            System.out.println(i / j);
        }
    };
    WrapperRunnable wrapperRunnable = new WrapperRunnable(runnable);
    executor.execute(wrapperRunnable);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 2011-11-16
      • 1970-01-01
      • 1970-01-01
      • 2014-05-20
      • 2014-03-18
      • 2011-08-24
      相关资源
      最近更新 更多