Skip to content

Thread&ThreadPoolExecutor异常处理 #27

@4rnold

Description

@4rnold

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-----------");
    }
}

参考

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions