2011-09-13 3 views
7

Java 및 동시성에 대한 질문이 있습니다.Java 캐시 된 스레드 풀 및 스레드 로컬

즉, a라는 ThreadLocal 변수가 있다고 가정 해 보겠습니다. 그리고 CachedThreadPool을 사용하여 새 스레드를 얻습니다. 스레드가 재사용 될 때 ThreadLocal 변수는 어떻게됩니까? 동일한 값을 유지하거나 (동일한 스레드이므로) 빈 상태로 시작합니다 (스레드가 새 것처럼).

감사 스레드 풀에 반환되면

답변

10

기본적으로 ThreadLocals는 스레드와 함께 재사용됩니다. 당신이 다시 초기화 할을해야 할 경우, 아래에 언급 된 방법을 대체하여 수행 할 수 있습니다 :

from javadoc for java.util.concurrent.ThreadPoolExecutor

후크 방법 이 클래스는 재정의 beforeExecute (java.lang.Thread에, 자바를 보호 제공합니다. lang.Runnable) 및 afterExecute (java.lang.Runnable, java.lang.Throwable) 메소드를 호출하여 각 태스크의 실행 전후에 호출됩니다. 이들은 실행 환경을 조작하는 데 사용할 수 있습니다. 예를 들어, ThreadLocals를 다시 초기화하거나, 통계를 수집하거나, 로그 항목을 추가 할 수 있습니다. 또한, Executed가 완전히 종료되면 완료되어야하는 특수 처리를 수행하기 위해 terminated() 메소드를 재정의 할 수 있습니다. 훅 또는 콜백 메서드가 예외를 throw하면 내부 작업자 스레드가 실패하고 갑자기 종료 될 수 있습니다.

+1

해결할 수있는 문제 나는 ThreadPoolExecutor가 스레드 로컬을 인식 할 필요가 있다는 것을 알았다. 나쁜 분열의 종류. 스레드가 실행을 끝내면 이벤트를 발생시키는 관찰자가 해결할 수 있습니다. 특정 스레드 로컬은 afterExecute 이벤트가 발생하면 클린업을 등록 (옵저버) 할 수 있습니다. –

3

는 ThreadLocal 변수는 여전히에 첨부됩니다. 풀과 함께 ThreadLocals를 사용할 때 스레드가 풀에서 꺼내어지고 반환되기 전에 설정 해제되도록 설정할 수 있도록주의해야합니다.

2

리플렉션을 사용하여 스레드에 대한 스레드 로컬 풀을 지울 수 있습니다. 할 수있다

public static void clearAllThreadLocals() { 
    try { 
     Field threadLocals = Thread.class.getDeclaredField("threadLocals"); 
     threadLocals.setAccessible(true); 
     threadLocals.set(Thread.currentThread(), null); 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
}