2009-09-29 12 views

답변

71

스레드가 동시에 같은 코드를 실행할 수있는 실행 스레드 등 다수의 단위이다. 객체/인스턴스에서 동시에 여러 스레드가 실행되는 경우 인스턴스 변수를 공유합니다. 각 스레드는 자체 로컬 변수를 가지지 만 매개 변수를 전달하지 않고 객체간에 공유하기가 어렵습니다.

가장 좋은 설명은 예제입니다. 로그인 한 사용자를 얻은 다음 몇 가지 코드를 실행하는 서블릿이 있다고 가정 해보십시오.

doGet(HttpServletRequest req, HttpServletResponse resp) { 
    User user = getLoggedInUser(req); 
    doSomething() 
    doSomethingElse() 
    renderResponse(resp) 
} 

doSomething() 메소드가 사용자 객체에 액세스해야한다면 어떻게 될까요? 각 스레드가 동일한 사용자 객체를 사용하기 때문에 사용자 객체를 인스턴스 또는 정적 변수로 만들 수 없습니다. 당신은 매개 변수로 주위에 사용자 개체를 전달할 수 있지만이 신속하게 모든 메소드 호출에 사용자 개체를 지저분하게하고 누수 :

doGet(HttpServletRequest req, HttpServletResponse resp) { 
    User user = getLoggedInUser(req); 
    doSomething(user) 
    doSomethingElse(user) 
    renderResponse(resp,user) 
} 

더 우아한 해결책이 ThreadLocal를

doGet(HttpServletRequest req, HttpServletResponse resp) { 
    User user = getLoggedInUser(req); 
    StaticClass.getThreadLocal().set(user) 
    try { 
    doSomething() 
    doSomethingElse() 
    renderResponse(resp) 
    } 
    finally { 
    StaticClass.getThreadLocal().remove() 
    } 
} 
에 사용자 개체를 넣어하는 것입니다

이제 그 성가신 추가 매개 변수에 의존 할 필요없이 로컬 스레드에서 추출하여 잡아 수있는 시간에 사용자 개체를 필요로하는 모든 코드 :

User user = StaticClass.getThreadLocal().get() 

이 방법을 사용하는 경우 finally 블록에서 오브젝트를 다시 제거해야합니다. 그렇지 않으면 Tomcat 응용 프로그램 서버와 같은 스레드 풀을 사용하는 환경에서 사용자 객체가 멈출 수 있습니다.

편집 : 정적 클래스의 코드는

class StaticClass { 
    static private ThreadLocal threadLocal = new ThreadLocal<User>(); 

    static ThreadLocal<User> getThreadLocal() { 
    return threadLocal; 
    } 
} 
+1

여기에 StaticClass 란 무엇입니까? 스레드를 확장하는 클래스? – Ajay

+0

StaticClass는 ThreadLocal 객체를 가져 오는 편리한 방법입니다. 예제를 수정하여 StaticClass에 대한 코드를 포함시킵니다. – leonm

+7

나는 그것이 항상 더 우아하다고 말하지 않을 것이지만, 더 편리하다. –

7

스레드 객체는 내부 데이터 멤버를 가질 수 있지만, 이러한 스레드 객체에 대한 참조를 가지고 (또는 얻을 수있는) 사람에 액세스 할 수 있습니다. ThreadLocal은 의도적으로 액세스하는 각 스레드와 만 연관됩니다. 장점은 동시성 문제가 없다는 것입니다 (ThreadLocal의 컨텍스트 내에서). 스레드의 내부 데이터 멤버는 공유 상태가 수행하는 모든 동시성 문제를 가지고 있습니다.

결과를 특정 스레드와 연관시키는 아이디어를 설명하겠습니다.

public class MyLocal<T> { 
    private final Map<Thread, T> values = new HashMap<Thread, T>(); 

    public T get() { 
    return values.get(Thread.currentThread()); 
    } 

    public void set(T t) { 
    values.put(Thread.currentThread(), t); 
    } 
} 

지금 그것보다 더있다 그러나 당신이 볼 수 있듯이 반환 값이 현재의 thread에 의해 결정됩니다 ThreadLocal을의 본질은이 같은 것입니다. 그래서 각 스레드에 대해 로컬입니다.

+0

의도적으로 각 스레드 의미와 관련이 있습니까? 스레드 자체가 바로 객체입니까? 따라서 실제로 스레드와 관련된 것은 스레드 객체와 관련이 있음을 의미합니까? – Ajay

+0

@Ajay : 예. ThreadLocal 인스턴스는, Thread 오브젝트에 부속 세미 데이터 구조를 개입시켜 Thread 오브젝트에 관련 지을 수 있습니다. "package private"멤버 참조 Thread.threadLocals and Thread.inherittableThreadLocals –

+0

@Stephen : Thread 클래스를 사용하는 것에 비해 threadLocal을 사용하면 어떤 차이가 있습니다. – Ajay

1

ThreadLocals을의 장점은 일반 바닐라 스레드 ... 또는 스레드의 서브 클래스에서 실행 방법으로 사용할 수 있다는 것입니다. 스레드 주민이 스레드의 사용자 지정 하위 클래스의 구성원으로 구현해야하는 경우

는 대조적으로, 당신이 할 수없는 많은 일들이 있습니다. 예를 들어, 기존의 바닐라 스레드 인스턴스에서 메소드를 실행해야하는 경우 응용 프로그램에 문제가 발생할 수 있습니다. 즉 응용 프로그램 작성자가 작성하지 않았으며 수정할 수없는 일부 라이브러리 코드로 작성된 인스턴스.

5

의 ThreadLocal는 webapplications에 매우 유용합니다. 전형적인 패턴은 웹 요청 처리 (대개 서블릿 필터에서) 상태가 ThreadLocal 변수에 저장된다는 것입니다. 요청에 대한 모든 처리가 1 스레드에서 수행되기 때문에 요청에 참여하는 모든 구성 요소는이 변수에 액세스 할 수 있습니다.

2

이 문제 영역은 위키 백과 entry about입니다. 우리 환경에서는 대개 로컬 요청을 요청하는 데 사용됩니다. 서버 측에서는 요청이 대부분 단일 스레드에 의해 처리됩니다. 일을 로컬로 유지하려면 데이터를 넣어야합니다 (예 : 스레드 로컬 변수의 세션 데이터 이 데이터는 다른 요청 (스레드)에서 볼 수 없으므로 다른 요청과 동기화 할 필요가 없습니다.

잊지 마세요. 이 아닌 자바 API 구조가 있습니다.은 thread safe합니다. DateFormat. DateFormat의 정적 인스턴스는 서버 측에서 작동하지 않습니다.

사실, 잠금 및 모니터로 처리하는 것보다 자신의 개인 데이터 복사본을 사용할 때 멀티 스레드 프로그래밍을 처리하는 것이 더 쉽습니다.

10

당신은 스레드를 확장하는 클래스의 인스턴스가 하지 실제 Java 스레드와 같은 일이 것을 깨닫게해야 당신의 코드를 실행하고 실행하는 "실행 포인터"로 상상 할 수 ().

이러한 클래스의 인스턴스는으로 Java 스레드를 나타내며 (예 : 인터럽트)이를 처리 할 수는 있지만 일반 객체 일 뿐이며 그 구성원은 보유 할 수있는 모든 스레드에서 액세스 할 수 있습니다 객체에 대한 참조입니다 (즉 not hard).

물론 멤버를 비공개로 유지하고이 멤버가 호출 된 run() 또는 메서드 (공용 메서드는 다른 스레드에서도 호출 할 수 있음)에서만 사용되도록 할 수는 있지만 오류가 발생하기 쉽고 그렇지 않은 것입니다. 더 복잡한 시스템에서 실제로 쓰레드 하위 클래스에 데이터를 보관하고 싶지는 않습니다. 실제로는 스레드를 서브 클래스 화하지 않고 대신 Runnable을 사용하는 것이 좋습니다.

ThreadLocal은 스레드 당 데이터가 일 수없는 간단하고 유연한 방법으로 다른 스레드에서 동시에 액세스 할 수 없습니다. 많은 노력이나 설계상의 타협이 필요하지 않습니다.

관련 문제