fix: EgovReflectionSupport 멀티스레드 lazy-init 경합 제거 (getter 메서드맵 부분초기화 NPE)#240
Open
z3rotig4r wants to merge 1 commit into
Open
fix: EgovReflectionSupport 멀티스레드 lazy-init 경합 제거 (getter 메서드맵 부분초기화 NPE)#240z3rotig4r wants to merge 1 commit into
z3rotig4r wants to merge 1 commit into
Conversation
EgovFieldExtractor·EgovJdbcBatchItemWriter 는 FieldExtractor/ItemWriter 빈으로 등록되어 멀티스레드 step 에서 공유되며, 그 안의 EgovReflectionSupport 인스턴스도 함께 공유된다. generateGetterMethodMap 은 methods 를 먼저 대입한 뒤 methodMap 을 채웠다. 이로 인해 한 스레드가 methods 만 비-null 로 만든 상태에서 다른 스레드가 `methods != null` 조건만 보고 아직 채워지지 않은(또는 null 인) methodMap 을 사용하여 NPE 가 발생할 수 있었다(cold-start 경합). double-checked locking 으로 초기화를 1회만 수행하고, methods·methodMap 을 지역변수로 완성한 뒤 methodMap 을 먼저 발행하고 methods 를 마지막에 대입하여 부분초기화 상태가 외부에 보이지 않게 한다. 두 필드를 volatile 로 선언해 가시성을 보장한다. 단일스레드 동작은 동일하다. EgovReflectionSupportConcurrencyTest 를 추가한다(32스레드 cold-start 동시호출 + 단일스레드 회귀). 수정 전에는 round 0 에서 NullPointerException 으로 실패하고 수정 후 통과한다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
배치 reflection 헬퍼
EgovReflectionSupport(Batch/.../reflection/EgovReflectionSupport.java)의generateGetterMethodMap에 멀티스레드 lazy-init 경합이 있어 수정합니다.문제
EgovFieldExtractor(FieldExtractor)·EgovJdbcBatchItemWriter(ItemWriter)는 빈으로 등록되어 멀티스레드 step(taskExecutor)에서 공유되며, 내부의EgovReflectionSupport인스턴스도 함께 공유됩니다.스레드 A가 (1)만 수행한 상태에서 스레드 B가
methods != null만 보고 블록을 건너뛰면, 아직 채워지지 않은(또는 null 인)methodMap을invokeGettterMethod에서 사용하여NullPointerException이 발생합니다(고정길이 레코드가 아닌, 조회 결과 누락/예외). cold-start 시 재현되는 전형적인 부분초기화 발행(publication) 버그입니다.EgovFixedLengthLineAggregator(별도 PR)와 동일한 "공유 인스턴스 + lazy-init" 패턴의 형제 사례입니다.수정
methods·methodMap을 지역변수로 완성한 뒤,methodMap을 먼저 발행하고methods를 마지막에 대입 → 부분초기화 상태가 외부에 보이지 않음.volatile로 선언해 가시성 보장.검증
EgovReflectionSupportConcurrencyTest추가:sharedInstanceColdStartIsThreadSafe— 32스레드 × 500라운드, 라운드마다 새 공유 인스턴스로 cold-start 동시호출.singleThreadGetterExtractsValues— 단일스레드 추출 회귀.수정 전 코드에서는
round 0에서NullPointerException(HashMap.get(...) is null)으로 실패하고, 수정 후 통과합니다.