一个线程运行过程中 如果发生不可恢复的错误 会导致线程退出.在java的世界里面 提供了UncaughtExceptionHandler 让应用开发人员捕捉到这种异常情况.jdk注释如下.
/**
* Interface for handlers invoked when a <tt>Thread</tt> abruptly
* terminates due to an uncaught exception.
* <p>When a thread is about to terminate due to an uncaught exception
* the Java Virtual Machine will query the thread for its
* <tt>UncaughtExceptionHandler</tt> using
* {@link #getUncaughtExceptionHandler} and will invoke the handler's
* <tt>uncaughtException</tt> method, passing the thread and the
* exception as arguments.
* If a thread has not had its <tt>UncaughtExceptionHandler</tt>
* explicitly set, then its <tt>ThreadGroup</tt> object acts as its
* <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
* has no
* special requirements for dealing with the exception, it can forward
* the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
* default uncaught exception handler}.
*
* @see #setDefaultUncaughtExceptionHandler
* @see #setUncaughtExceptionHandler
* @see ThreadGroup#uncaughtException
* @since 1.5
*/
学习zookeeper 源码过程中 发现zookeeper 提供了Listener这种更友好的方法 代码如下
ZookeeperThread
/**
* This is the main class for catching all the uncaught exceptions thrown by the
* threads.
*/
public class ZooKeeperThread extends Thread {
private static final Logger LOG = LoggerFactory
.getLogger(ZooKeeperThread.class);
private UncaughtExceptionHandler uncaughtExceptionalHandler = new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
handleException(t.getName(), e);
}
};
public ZooKeeperThread(Runnable thread, String threadName) {
super(thread, threadName);
setUncaughtExceptionHandler(uncaughtExceptionalHandler);
}
public ZooKeeperThread(String threadName) {
super(threadName);
setUncaughtExceptionHandler(uncaughtExceptionalHandler);
}
/**
* This will be used by the uncaught exception handler and just log a
* warning message and return.
*
* @param thName
* - thread name
* @param e
* - exception object
*/
protected void handleException(String thName, Throwable e) {
LOG.warn("Exception occured from thread {}", thName, e);
}
}
ZooKeeperCriticalThread
/**
* Represents critical thread. When there is an uncaught exception thrown by the
* thread this will exit the system.
*/
public class ZooKeeperCriticalThread extends ZooKeeperThread {
private static final Logger LOG = LoggerFactory
.getLogger(ZooKeeperCriticalThread.class);
private final ZooKeeperServerListener listener;
public ZooKeeperCriticalThread(String threadName,
ZooKeeperServerListener listener) {
super(threadName);
this.listener = listener;
}
/**
* This will be used by the uncaught exception handler and make the system
* exit.
*
* @param threadName
* - thread name
* @param e
* - exception object
*/
@Override
protected void handleException(String threadName, Throwable e) {
LOG.error("Severe unrecoverable error, from thread : {}", threadName, e);
listener.notifyStopping(threadName, ExitCode.UNEXPECTED_ERROR);
}
}
**ZooKeeperServerListener **
/**
* Listener for the critical resource events.
*/
public interface ZooKeeperServerListener {
/**
* This will notify the server that some critical thread has stopped. It
* usually takes place when fatal error occurred.
*
* @param threadName
* - name of the thread
* @param errorCode
* - error code
*/
void notifyStopping(String threadName, int errorCode);
}