I. Overview
Why separate the multi-threaded exception capture? Let's look at an example:
Publicclass ThreadException implements runnable{@Override Publicvoid Run () {throw new RuntimeException (); } //Symptom: The console prints out the exception information and runs for a period of time before stopping Publicstatic void Main (String[]args) { //Even if you put the execution statement of the thread into the try-the catch block is useless try{executorserviceexec =Executors.newcachedthreadpool (); exec.Execute(New ThreadException ()); }catch (RuntimeException e) {System.out.println ("Exception has been handled!"); } }}
A run-time exception was thrown manually in run, the thread is started in main, the catch statement block catches the exception, and a word is snapped to print. Running results such as:
The exception was found to be thrown to the console without printing the statement in the catch block.
Conclusion: Multithreaded operations cannot handle exceptions in the same way that an exception is caught in sequential execution, and exceptions are thrown directly to the console (because of the nature of the thread, you cannot capture an exception that escapes from the thread.) Once an exception escapes the task's Run method, it propagates outwards to the console unless you catch the exception in a special form. This can make you a headache, and you can't catch the problem that the exception is not able to handle the exception.
So, how do we want to catch exceptions in multi-threading?
Catching exceptions in multiple threads
Let's follow the steps below to complete this experiment:
1. Defining the exception handler
Requirements, implement the Thread.uncaughtexceptionhandler Uncaughtexception method, as follows:
/**/classimplements thread.uncaughtexceptionhandler{ /* * Thread.UncaughtExceptionHandler.uncaughtException () will be called when the thread is near death due to an uncaught exception */ @Override publicvoid uncaughtexception (Thread T, throwable e) { System.out.println ("caught " +e); }}
2. Define a thread factory that uses this exception handler
/** Step two: Define the Thread factory * thread factory is used to attach the task to the thread and bind the thread to an exception handler*/classHanlderthreadfactoryImplementsthreadfactory{@Override PublicThread Newthread (Runnable R) {System.out.println ( This+ "Creating new Thread"); Thread T=NewThread (R); System.out.println ("Created" +t); T.setuncaughtexceptionhandler (NewMyuncaughtexceptionhandler ()); //Set exception handler for thread factory System.out.println ("Eh=" +T.getuncaughtexceptionhandler ()); returnT; }}
3. Define a task and let it throw an exception
/**/classimplements runnable{ @Overridepublic void run () { = thread.currentthread (); System.out.println ("Run () by" +T); System.out.println ("eh =" +T.getuncaughtexceptionhandler ()); Throw New runtimeexception (); }}
4. Invoke the experiment
/**/Publicclass threadexceptionuncaughtexceptionhandler{ Public Static void Main (string[] args) { = Executors.newcachedthreadpool (new hanlderthreadfactory ()); Exec.execute (new exceptionthread ());} }
Running results such as:
Iii. Conclusion
In Java, to catch the exceptions generated by multithreading, you need to customize the exception handler and set it to the corresponding thread factory (that is, the first and second steps).
Iv. expansion
If you know that you are going to use the same exception handler everywhere in your code, the easier way is to set up a static domain in the thread class and set the processor as the default uncaught processor.
This processor is called only if there is no exception handler that is not caught by the thread.
Public Static void Main (string[] args) { Thread.setdefaultuncaughtexceptionhandler (new Myuncaughtexceptionhandler ()); =Executors.newcachedthreadpool (); Exec.execute (new exceptionthread ());}
Note: The above code is from the "Thinking in Java", the content is their own summary, if there are errors, you are welcome to criticize
Java Multithreading--< seven > Multi-threading Exception snapping