>  기사  >  Java  >  Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

WBOY
WBOY앞으로
2022-05-09 17:49:493428검색

이 기사에서는 java에 대한 관련 지식을 제공합니다. 여기서는 예외 캡처 및 트랜잭션 롤백 등을 포함하여 하위 스레드 작업에서 예외가 발생할 때 메인 스레드 트랜잭션을 롤백하는 방법에 대한 관련 문제를 주로 소개합니다. 아래 내용이 모든 분들께 도움이 되기를 바랍니다.

Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

추천 학습: "java 비디오 튜토리얼"

1. 질문하기

메인 스레드가 스레드 풀에 작업을 제출했습니다. 이 작업을 실행하는 동안 예외가 발생하면 어떻게 될까요? 메인 스레드에서 예외가 포착되고 트랜잭션이 롤백됩니다.

2. 메인 스레드와 서브 스레드

먼저 기본 사항을 살펴보겠습니다. 아래 그림은 두 스레드의 실행 모드를 보여줍니다.

  • 왼쪽 그림은 메인 스레드 이후를 보여줍니다. 서브 스레드를 시작하고 두 번째는 서로 간섭하지 않고 독립적으로 작동합니다. 이제부터 당신과 나는 운명에 따라 결정됩니다.
  • 오른쪽 그림은 메인 스레드가 하위 스레드를 시작한 후 계속해서 메인 스레드 프로그램 로직을 실행하고 특정 노드에서 차단하여 하위 스레드의 실행 결과를 얻는 것을 보여줍니다.

Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

위에서 제기된 문제에 대해 두 번째 방법은 하위 스레드 실행 중에 발생하는 예외를 메인 스레드에서 캡처할 수 있다는 문제를 해결하는 것이어야 합니다. 여기서 인터뷰 질문을 드리고 싶습니다. 스레드를 구현하는 두 인터페이스 Callable과 Runnable의 차이점은 다음과 같습니다.

public interface Callable<v> {
    V call() throws Exception;}</v>
public interface Runnable {
    public abstract void run();}

call 메소드에는 반환 값이 있고 run 메소드에는 반환 값이 없는 것을 볼 수 있습니다. 또한, call 메소드는 예외를 발생시킬 수 있지만 run 메소드는 예외를 발생시킬 수 없습니다. 분명히 하위 스레드의 실행 결과나 실행 예외를 캡처하거나 알기 위해서는 Callable 인터페이스를 통해 이를 구현해야 합니다.

여기에서는 Callable 인터페이스를 구현하고 너무 많은 작업을 수행하지 않고 널 포인터 예외를 직접 발생시키는 ExpSubThread 클래스(하위 스레드 예외 시뮬레이션 클래스)를 작성합니다.

public class ExpSubThread implements Callable {
    @Override
    public Object call() throws Exception {
        throw new NullPointerException();
    }}

3. 스레드 풀

스레드 작업에 직면하면 일반적으로 스레드 풀은 미리 계획된 n개의 스레드 리소스 모음입니다. 장점은 다음과 같습니다.

  • 작업을 실행할 때 새 스레드를 생성하지 않고 스레드 풀에 있는 기존 스레드 리소스를 사용합니다. 작업 실행이 완료되면 스레드 리소스는 소멸되지 않지만 스레드 리소스는 스레드 풀로 반환됩니다. 따라서 쓰레드 생성과 소멸에 소모되는 자원이 어느 정도 절약되어 쓰레드 자원 재사용 목적이 달성된다.
  • 스레드 풀 생성 크기에는 상한이 있기 때문에 스레드 풀의 또 다른 기능은 스레드의 무제한 생성을 방지하고 무제한 애플리케이션 리소스 점유로 인한 시스템 충돌을 방지하는 것입니다.

일반적으로 사용되는 스레드 풀에는 두 가지가 있습니다. 하나는 JDK와 함께 제공되는 것이고 다른 하나는 Spring 스레드 풀입니다. 후자는 Spring 환경에서 자주 사용되며 유사합니다. 여기서는 Spring API를 사용하여 스레드 풀을 구축합니다.

public ThreadPoolTaskExecutor getThreadPool(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(100);  //线程池最大线程数
        executor.setCorePoolSize(50);//线程池核心线程数
        executor.setQueueCapacity(50);//任务队列的大小
        executor.setThreadNamePrefix("test_"); //线程前缀名
        executor.initialize(); //线程初始化
        return executor;}

4. 예외 캡처

다음은 제가 작성한 테스트 케이스로, 메인 스레드의 프로그램 실행 흐름을 나타냅니다.

@Testvoid subThreadExceptionTest() {
        try{
            //新建子线程对象
            ExpSubThread expSubThread = new ExpSubThread();
            //构建线程池
            ThreadPoolTaskExecutor executor = getThreadPool();
            //提交子线程任务,submit方法
            Future future = executor.submit(expSubThread);
            //在这里可以做主线程的业务其他流程操作
            //阻塞等待子线程的执行结果
            Object obj = future.get();  
        }catch (Exception e){
            e.printStackTrace();
            //事务回滚
        }}

여기서 주목해야 할 것은 submit 메소드를 사용하여 하위 스레드 작업을 제출한다는 것입니다. 실행을 위해 스레드 풀로 이동합니다. ThreadPoolTaskExecutor에는 스레드 작업을 실행하는 두 가지 메서드가 있습니다. 하나는 실행 메서드이고 다른 하나는 제출 메서드입니다.

  • 실행 메소드에는 반환 값이 없으므로 작업이 성공적으로 완료되었는지 판단할 수 없습니다. 해당 스레드 클래스는 Runnable 인터페이스를 구현합니다.
  • 제출 메소드에는 Future를 반환하는 반환 값이 있으며 해당 스레드 클래스는 Callable 인터페이스를 구현합니다.

Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

Future.get() 메소드는 메인 스레드를 차단하는 목적을 달성하므로 하위 스레드 작업의 실행 결과를 판단할 수 있으며 get 메소드는 예외를 발생시킬 수 있습니다.

    V get() throws InterruptedException, ExecutionException;

아래 그림은 위의 테스트 케이스 프로그램e.printStackTrace();의 효과입니다. 그림에서 두 가지 예외 예외를 볼 수 있습니다. 하나는 하위 스레드 작업에서 시뮬레이션된 방식으로 적극적으로 던지는 null 포인터 예외입니다. 다른 하나는 널 포인터로 인해 get 메소드에서 발생한 ExecutionException입니다.

Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백

5. 트랜잭션 롤백

위에서 본 것처럼 스레드 반환 값을 얻거나 예외를 발생시키는 목적을 달성하기 위해

  • thread 클래스를 통해 Callable 인터페이스를 구현했습니다.
  • submit은 스레드 작업을 스레드 풀에 제출할 수 있으며 하위 스레드 실행 결과의 반환 값인 Future를 얻을 수 있습니다.
  • Future의 get() 메서드는 발생한 예외를 포함하여 하위 스레드 실행 정보를 얻을 수 있습니다.

이제 메인 스레드에서 서브 스레드의 예외 정보를 감지하거나 잡을 수 있게 되었는데, 다음 단계에서 메인 스레드의 트랜잭션을 롤백하는 것은 너무 단순한 걸까요?

  • jdbc는 conn.rollback()을 통해 트랜잭션 롤백을 구현합니다. conn.rollback()实现事务的回滚
  • spring环境下使用@Transactional
  • 스프링 환경에서 @Transactional 주석을 사용하면 됩니다.

추천 학습: "java 비디오 튜토리얼

"🎜

위 내용은 Java 예제에 대한 자세한 설명: 하위 스레드 작업 예외, 기본 스레드 트랜잭션 롤백의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제