如何在父线程中捕获来自子线程的异常呢

方法一:子线程中try... catch...

方法二:为线程设置异常处理器UncaughtExceptionHandler

(异常处理也是在子线程中执行,相当于在子线程中加上了一个异常拦截器,可以使用下面的程序验证)

(1)Thread.setUncaughtExceptionHandler设置当前线程的异常处理器

(2)Thread.setDefaultUncaughtExceptionHandler为整个程序设置默认的异常处理器

(3)new Thread(new ThreadTest() ,new runable{})时传入 ThreadGroup 

方法三,通过Future的get方法捕获子线程异常

 

import java.util.concurrent.*;

public class ThreadTest extends ThreadGroup{

    private ThreadTest(){
        super("ThreadTest");
    }


    public static void main(String[] args) {

        System.out.println(Thread.currentThread().getId());

        Thread t1=new Thread(new ThreadTest(),new Runnable() {//传入继承ThreadGroup的类对象
            @Override
            public void run() {

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (1==1){
                    throw new NullPointerException("111");
                }
            }
        });
        t1.start();


        /*ExecutorService executorService = Executors.newFixedThreadPool(8);
        Future future = executorService.submit(()->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (1==1){
                throw new NullPointerException("111");
            }
            return 1;
        });

        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {

            //e.getCause().printStackTrace();
            e.printStackTrace();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdownNow();*/


    }

    public   void   uncaughtException(Thread   thread,   Throwable   exception)
    {
        /**
         * 当线程抛出unckecked异常时,系统会自动调用该函数,但是是在抛出异常的线程内执行*/
        System.out.println(Thread.currentThread().getId());
        System.out.println(thread.getId());
        exception.printStackTrace();//example,   print   stack   trace
    }
}

 线程池阻塞方法的使用  future.get()

1.LockSupport.park()消费一个信号量,会一直阻塞,LockSupport.park(thread)增加一个信号量

2.UNSAFE.park(false, 0L) 消费一个信号量 会一直阻塞 UNSAFE.unpark(thread) 增加一个信号量

3.和wait,notify(),notifyAll()相比的优点

3.1 park 和 unpark无先后顺序 而wait,notify(),notifyAll() 有严格顺序

3.2 park 和 unpark