>Java >java지도 시간 >Java 하위 스레드의 일반적인 예외 처리 방법 소개

Java 하위 스레드의 일반적인 예외 처리 방법 소개

黄舟
黄舟원래의
2017-09-26 09:27:241622검색

다음 편집기는 Java 하위 스레드(일반)의 예외 처리 방법을 기반으로 한 기사를 제공합니다. 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 편집기를 따라가서 살펴보겠습니다. 일반적인 단일 스레드 프로그램에서 예외를 포착하려면 try...catch...finally...code 블록만 필요합니다. 그렇다면 동시 상황(예: 하위 스레드가 상위 스레드에서 시작되는 경우)에서 상위 스레드의 하위 스레드에서 예외를 포착하고 그에 따라 처리하는 방법은 무엇입니까?

일반적인 실수어떤 사람들은 매우 간단하다고 생각할 수도 있습니다. 시도해 보세요. 상위 스레드가 하위 스레드를 시작하는 위치를 직접 잡아보세요. 사실 이것은 잘못된 것입니다.

원인 분석Runnable 인터페이스의 run 메서드의 전체 서명을 기억해 보겠습니다. throws 문이 식별되지 않기 때문에 메서드는 확인된 예외를 발생시키지 않습니다. RuntimeException과 같은 확인되지 않은 예외의 경우 JVM에 의해 새 스레드가 예약되고 실행되므로 예외가 발생하면 상위 스레드에 알리지 않습니다.

public abstract void run()

Solution그럼 상위 스레드의 하위 스레드에서 예외를 포착하는 방법은 무엇일까요? 저자는 3가지 일반적인 방법을 생각해 모두와 공유했다.

방법 1: 자식 스레드에서 try...catch... 가장 간단하고 효과적인 방법은 예외가 발생할 수 있는 자식 스레드의 메서드에서 try...catch를 사용하는 것입니다. .. 문이 래핑되었습니다. 하위 스레드 코드:

public class ChildThread implements Runnable {
 public void run() {
  doSomething1();
  try {
   // 可能发生异常的方法
   exceptionMethod();
  } catch (Exception e) {
   // 处理异常
   System.out.println(String.format("handle exception in child thread. %s", e));
  }
  doSomething2();
 }
}

방법 2: 스레드에 대한 예외 처리기 UncaughtExceptionHandler를 설정합니다.스레드에 대한 예외 처리기를 설정합니다. 구체적인 방법은 다음과 같습니다.

(1) Thread.setUncaughtExceptionHandler는 현재 스레드의 예외 핸들러를 설정합니다.

(2) Thread.setDefaultUncaughtExceptionHandler는 현재 스레드에 예외 핸들러가 있는 경우 전체 프로그램에 대한 기본 예외 핸들러를 설정합니다. (기본값은 없음)) UncaughtExceptionHandler 클래스가 먼저 사용됩니다. 그렇지 않으면 현재 스레드가 속한 스레드 그룹에 예외 핸들러가 있으면 스레드 그룹의 ExceptionHandler가 사용됩니다. 그렇지 않으면 전역 기본값인 DefaultUncaughtExceptionHandler가 사용됩니다. 아무것도 없으면 하위 스레드가 종료됩니다.

참고: 하위 스레드에서 예외가 발생하는 경우 처리를 담당할 클래스가 없으면 로그를 남기지 않고 바로 종료됩니다. 따라서 아무것도 하지 않으면 하위 스레드 작업이 실행되지 않고 로그 프롬프트도 나오지 않는 '이상한' 현상이 발생하게 됩니다.

현재 스레드에 대한 예외 핸들러 설정:

public class ChildThread implements Runnable { 
 private static ChildThreadExceptionHandler exceptionHandler;

 static {
  exceptionHandler = new ChildThreadExceptionHandler();
 }

 public void run() {
  Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler);
  System.out.println("do something 1");
  exceptionMethod();
  System.out.println("do something 2");
 }

 public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
  public void uncaughtException(Thread t, Throwable e) {
   System.out.println(String.format("handle exception in child thread. %s", e));
  }
 }
}

또는 모든 스레드에 대한 기본 예외 핸들러 설정

public class ChildThread implements Runnable {
 private static ChildThreadExceptionHandler exceptionHandler;

 static {
  exceptionHandler = new ChildThreadExceptionHandler();
  Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
 }

 public void run() {
  System.out.println("do something 1");
  exceptionMethod();
  System.out.println("do something 2");
 }

 private void exceptionMethod() {
  throw new RuntimeException("ChildThread exception");
 }

 public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
  public void uncaughtException(Thread t, Throwable e) {
   System.out.println(String.format("handle exception in child thread. %s", e));
  }
 }
}

명령줄 출력: 1

하위 스레드에서 예외를 처리합니다. lang .RuntimeException: ChildThread 예외

방법 3, Future의 get 메소드를 통해 예외를 포착합니다스레드 풀을 사용하여 반환 정보를 얻을 수 있는 메소드, 즉 ExecutorService.submit(Callable)을 제출합니다. 스레드 실행 결과의 Future 객체를 제출한 후 메서드를 얻을 수 있습니다. 자식 스레드에서 예외가 발생하면 future.get()을 통해 반환 값을 얻을 때 ExecutionException 예외를 catch하여 예외가 발생했음을 알 수 있습니다. 하위 스레드에서.

하위 스레드 코드:

public class ChildThread implements Callable {
 public Object call() throws Exception {
  System.out.println("do something 1");
  exceptionMethod();
  System.out.println("do something 2");
  return null;
 }

 private void exceptionMethod() {
  throw new RuntimeException("ChildThread1 exception");
 }
}

상위 스레드 코드:

public class Main {
 public static void main(String[] args) {
  ExecutorService executorService = Executors.newFixedThreadPool(8);
  Future future = executorService.submit(new ChildThread());
  try {
   future.get();
  } catch (InterruptedException e) {
   System.out.println(String.format("handle exception in child thread. %s", e));
  } catch (ExecutionException e) {
   System.out.println(String.format("handle exception in child thread. %s", e));
  } finally {
   if (executorService != null) {
    executorService.shutdown();
   }
  }
 }
}

명령줄 출력: 1

하위 스레드에서 예외를 처리합니다. java.lang.RuntimeException : ChildThread1 예외

요약위는 일반적으로 사용되는 Java 하위 스레드 예외 처리 방법 3가지입니다. 사실 작성자는 특정 시나리오에서 여러 가지 다른 솔루션도 생각했습니다. 나중에 분석해 보겠습니다. 지원해 주셔서 감사합니다~

위 내용은 Java 하위 스레드의 일반적인 예외 처리 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.