Java 멀티 스레드 실행 메서드에서 서비스 비즈니스 클래스를 사용하면 java.lang.NullPointerException 예외가 발생하기 때문입니다. spring에 의해 주입된 것은 null이거나 직접적으로 새로운 비즈니스 객체도 null입니다.
멀티스레딩은 스레드 안전을 위해 주입을 방지하므로 서비스 비즈니스 클래스를 사용하려면 ApplicationContext 메소드를 사용하여 Bean 메소드를 얻어야 서비스 클래스를 얻을 수 있습니다.
ApplicationContext 클래스를 얻으려면 다음과 같이 ApplicationContextAware 인터페이스를 구현해야 합니다.
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext context; public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } public static ApplicationContext getContext() { return context; } }
그런 다음 run 메서드에서 위의 메서드를 사용하여 다음과 같이 비즈니스 개체를 생성합니다.
XXXServiceI xxxService = ApplicationContextUtil.getContext.getBean(XXXServiceI.class);
이런 방식으로 다음을 사용할 수 있습니다. 보통 비즈니스석.
1. Thread 클래스를 상속받아 Thread의 실행 메소드를 다시 작성하고, run 메소드 사용 start 메소드는 스레드를 시작합니다
2. Runnable 인터페이스를 상속하고, run 메소드를 구현하고, run 메소드에서 작동합니다. Thread를 생성하려면 현재 클래스의 인스턴스 객체를 전달해야 합니다. 그런 다음 start 메소드를 호출하여 스레드를 시작합니다
3. Callable 인터페이스를 구현하고 call() 메소드를 다시 작성합니다. 처음 두 메소드는 응답이 필요하지 않으며 직접 실행됩니다. 그러나 Callable 인터페이스를 구현하고 call() 메소드를 다시 작성하려면 Responsive 스레드를 기다려야 하므로 다른 스레드가 시작되더라도 하나의 스레드가 실행되고 있으므로 표준 멀티스레딩으로 간주할 수 없습니다.
4. 스레드 풀
같은 클래스에서 메서드 A는 메서드 B를 참조하고 메서드 B는 비동기 @Async 주석을 추가하는데 이는 효과적이지 않습니다.
@Async 메소드가 추가됩니다. 호출자와 동일한 클래스에 있을 수 없습니다
Java에서 생성된 스레드는 기본적으로 새 스레드(스레드 객체)와 같은 사용자 스레드를 생성합니다.start
Thread thread = new Thread(); // 默认为false,都是用户线程 thread.setDaemon(true); // 表示设置为守护线程 thread.setDaemon(false); // 表示设置为用户线程
사용자 스레드: 다른 스레드가 죽어도 죽지 않습니다. 하나는 작동 중 예외로 인해 종료되는 경우이고 다른 하나는 프로그램이 정상적으로 실행되는 경우입니다. the thread dies
Daemon thread: 사용자 스레드가 죽으면 사용자 스레드도 죽습니다. 예를 들어 gc 가비지 수집 스레드도 죽습니다. 사용자 스레드가 존재한다면 gc는 살아 있어야 하며, 그렇지 않으면 쓸모가 없습니다.
1. 새로운 기능: 초기 상태, 스레드가 생성되고 start()가 호출되지 않음
2 실행 가능: 실행 가능 상태, Java 스레드는 작동 중 준비 상태와 실행 중 상태를 통합합니다. "실행 중"이라고 불리는 시스템
3. 차단됨, 스레드가 대기 상태에 들어가고 스레드가 어떤 이유로 CPU 사용 권한을 포기함
여러 가지 차단 상황:
A. 차단용: 실행 중인 스레드가 wait()를 실행하면 JVM은 현재 스레드를 대기 대기열에 넣습니다
B. 동기화 차단: 실행 중인 스레드가 객체의 동기화 잠금을 획득할 때 동기화 잠금이 점유된 경우 다른 스레드에 의해 JVM은 현재 스레드를 잠금 풀
C에 넣습니다. 기타 차단: 실행 중인 스레드가 sleep(), Join()을 실행하거나 IO 요청을 발행하면 JVM은 현재 스레드를 다음으로 설정합니다. 차단 상태. sleep()이 완료되면 Join() 스레드가 종료되고 IO 처리가 완료된 후 스레드가 다시 시작됩니다
4. 대기: 대기 상태
5. 시간 초과 대기 상태. 시간 초과 후 반환
6. 종료됨: 종료된 상태, 현재 스레드가 실행을 완료했습니다.
Java 잠금의 재진입 메커니즘은 다음 문제를 코드로 직접 해결할 수 있습니다.
public class Demo1 { public synchronized void functionA(){ System.out.println("iAmFunctionA"); functionB(); } public synchronized void functionB(){ System.out.println("iAmFunctionB"); }
Java가 원자성을 강제하는 동기화된 내부 잠금 메커니즘을 제공하지 않습니다. functionA() 및 functionB()는 모두 동기 메서드입니다. 스레드가 funcitonA()에 들어가면 이 잠금은 "new Demo1()"입니다. functionA()에서 functionB() 메소드가 호출되지만 functionB()도 동기식이므로 스레드는 다시 객체 잠금(new Demo1())을 획득해야 하지만 JVM은 이 스레드가 객체 잠금을 획득했다고 생각할 것입니다. 이 객체를 잠그고 다시 얻을 수 없으므로 functionB() 메서드를 호출할 수 없어 교착 상태가 발생합니다.
스레드 풀의 작업 캐시 큐가 가득 차고 스레드 풀의 스레드 수가 maximumPoolSize에 도달한 경우 아직 작업이 도착하면 작업 거부 전략이 채택됩니다. 일반적으로 네 가지 전략:
ThreadPoolExecutor.AbortPolicy
: 작업을 취소하고 RejectedExecutionException을 발생시킵니다. ThreadPoolExecutor.AbortPolicy
:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy
:丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy
:丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy
ThreadPoolExecutor.DiscardPolicy
: 작업을 삭제하지만 예외를 발생시키지는 않습니다.
ThreadPoolExecutor.DiscardOldestPolicy
: 대기열의 맨 앞에 있는 작업을 삭제한 다음 거부된 작업을 다시 제출합니다. ThreadPoolExecutor.CallerRunsPolicy
: 호출 스레드(제출한 스레드)에 의해 처리됩니다. 태스크) 이 작업sleep과 wait의 차이점위 내용은 Java 멀티스레드 실행 메소드에서 서비스 비즈니스 클래스를 직접 호출하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!