[JAVA] 쓰레드 - 3. UncaughtExceptionHandler

유알·2023년 2월 23일
0

[JAVA]

목록 보기
10/13

이번에는 UncaughtExceptionHandler 에 대해 알아보겠다.

사실 내가 보는 책이나 강의들에서는 잠깐 언급하고 지나갔지만, 내가 보기에는 꽤 중요한 부분이라고 생각되어서 따로 공부해서 적었다.

Thread.UncaughtExceptionHandler

Thread에 대한 JAVA api 를 확인하면 내부에 이러한 인터페이스가 있는 것을 발견할 수 있다.

//Thread 내부
    @FunctionalInterface
    public interface UncaughtExceptionHandler {

        void uncaughtException(Thread t, Throwable e);
    }

    // null unless explicitly set
    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

쓰레드에서 uncaughtException(처리되지 않은 예외)로 인해 쓰레드가 종료되려고 할 때,

  1. JVM은 쓰레드에게 Thread.getUncaughtExceptionHandler()을 통해 uncaughtExceptionHandler를 얻어냅니다.
    그리고 인수로 Thread와 Throwable을 넣어서 uncaughtException 메서드를 실행합니다.

  2. 이때 만약 명시적으로 UncaughtExceptionHandler가 설정되지 않았다면,
    ThreadGroup 오브젝트가 UncaughtExceptionHandler처럼 동작합니다.

  3. 만약 ThreadGroup 에 처리를 위한 특별한 요구사항이 없는 경우 Thread.getDefaultUncaughtExceptionHandler를 통해 얻어낸 defaultUncaughtExceptionHandler 를 통해 처리하려고 한다.

  4. 만약 이 마저도 없다면 아래와 같이 처리한다.

Thread.uncaughtExceptionHandler
ThreadGroup.uncaughtException()
Thread.defaultUncaughtExceptionHandler

public class ThreadGroup implements Thread.UncaughtExceptionHandler {
	//...
    public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) {
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) {
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }
    //...
}

즉 우리는 UncaughtExceptionHandle 을 하기 위해 아래와 같은 선택지가 있다.

  1. 쓰레드 하나에 적용하려면, public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
  2. 쓰레드 그룹에 적용하려면, ThreadGroup.uncaughtException()를 자손클래스에서 오버라이드
  3. 기본 처리를 바꾸려면, public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) 을 통해 바꿀 수 있다.

이 모든 단계는 앞의 단계가 null 일때 다음 단계를 검토한다.

즉 이 처리를 잘 적용하면 기본적인 에러를 쭉 print 하는 것이 아닌, 로그를 남긴다던가, 기록을 한다던가 하는 모든 처리가 가능하다.

그리고 마지막으로 api에는 이러한 줄이 적혀있다.

uncaughtException

Any exception thrown by this method will be ignored by the Java Virtual Machine.

이 메서드에서 던져지는 어떠한 exception 도 JVM에 의해 처리되지 않는다.

profile
더 좋은 구조를 고민하는 개발자 입니다

0개의 댓글