Catch exception (thread) study notes

Due to the nature of the thread, you cannot catch exceptions that escape from the thread. Once the exception escapes the task's run() method, it will be propagated to the console, unless special steps are taken to catch this wrong exception. Before java SE5, you can use thread groups to catch exceptions, but with java SE5, you can use Executor to solve this problem .

class ExceptionThread implements Runnable{
    
    
	public void run() {
    
    
		throw new RuntimeException();
	}
}
public class NaiveExceptionHandling {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		try {
    
    
            ExecutorService exec=Executors.newCachedThreadPool();
            exec.execute(new ExceptionThread());
		}catch(RuntimeException e) {
    
    
			System.out.println("Exception has been handled");
		}
	}

}
/*
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at demo.ExceptionThread.run(NaiveExceptionHandling.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
*/

After the above program is run, it is visible in the window and no "Exception has been handled" is printed, so the exception thrown in the thread cannot be caught in the try-catch clause.

To solve this problem, we need to modify the way the Executor generates threads.
Thread.UncaughtExceptionHandler is a new interface in java SE5, which allows you to attach an exception handler to each Thread object. Thread.UncaughtExceptionHandler.uncaughtException() will be called when the thread is about to die due to an uncaught exception.

class ExceptionThread2 implements Runnable{
    
    
	public void run() {
    
    
		Thread t=Thread.currentThread();
		System.out.println("run() by "+t);
		System.out.println("ek = "+t.getUncaughtExceptionHandler());
		throw new RuntimeException();
	}
}
class MyUncaughtExceptionHandler implements UncaughtExceptionHandler{
    
    

	@Override
	public void uncaughtException(Thread t, Throwable e) {
    
    
		// TODO Auto-generated method stub
		System.out.println("caught "+e);
	}
	
}
class HandlerThreadFactory implements ThreadFactory{
    
    

	@Override
	public Thread newThread(Runnable r) {
    
    
		// TODO Auto-generated method stub
		System.out.println(this+" creating new Thread");
		Thread t=new Thread(r);
		System.out.println("created "+t);
		t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
		System.out.println("eh = "+t.getUncaughtExceptionHandler());
		return t;
	}
	
}
public class CaptureUncaughtException {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
        ExecutorService exec=Executors.newCachedThreadPool(new HandlerThreadFactory());
        exec.execute(new ExceptionThread2());
	}

}
/*
demo.HandlerThreadFactory@4e25154f creating new Thread
created Thread[Thread-0,5,main]
eh = demo.MyUncaughtExceptionHandler@70dea4e
run() by Thread[Thread-0,5,main]
ek = demo.MyUncaughtExceptionHandler@70dea4e
demo.HandlerThreadFactory@4e25154f creating new Thread
created Thread[Thread-1,5,main]
eh = demo.MyUncaughtExceptionHandler@3670f81
caught java.lang.RuntimeException
*/

The above program creates a new type of ThreadFactory (by writing a customized ThreadFactory, you can customize the attributes (background, priority, name) of the thread created by the Excecutor.) , it will attach a Thread to each newly created Thread object. UncaughtExceptionHandler . We pass this factory to Executors to create a new ExecutorService method.

If you want to use the same exception handler everywhere in the code, the simpler way is to set a static field in the Thread class and set this handler as the default catch exception handler.
Thread.setDeflautUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
This handler will only be called when there is no thread-specific uncaught exception handler. That is, the above method is called last.

Guess you like

Origin blog.csdn.net/weixin_43916777/article/details/104242892