가능한 중복 : When and how should I use a Threadlocal variableThreadLocal의 목적은 무엇입니까?
변수가 ThreadLocal 변수를 포함하는 개체를 액세스하는 스레드 로컬 주어진 here 상태 등의 ThreadLocal의 용도. ThreadLocal 변수를 클래스의 멤버로 갖는 다음 Thread 자체에 로컬 변수를 가지지 않고 Thread에 로컬로 만들면 어떤 차이가 있습니까?
가능한 중복 : When and how should I use a Threadlocal variableThreadLocal의 목적은 무엇입니까?
변수가 ThreadLocal 변수를 포함하는 개체를 액세스하는 스레드 로컬 주어진 here 상태 등의 ThreadLocal의 용도. ThreadLocal 변수를 클래스의 멤버로 갖는 다음 Thread 자체에 로컬 변수를 가지지 않고 Thread에 로컬로 만들면 어떤 차이가 있습니까?
스레드가 동시에 같은 코드를 실행할 수있는 실행 스레드 등 다수의 단위이다. 객체/인스턴스에서 동시에 여러 스레드가 실행되는 경우 인스턴스 변수를 공유합니다. 각 스레드는 자체 로컬 변수를 가지지 만 매개 변수를 전달하지 않고 객체간에 공유하기가 어렵습니다.
가장 좋은 설명은 예제입니다. 로그인 한 사용자를 얻은 다음 몇 가지 코드를 실행하는 서블릿이 있다고 가정 해보십시오.
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;
}
}
스레드 객체는 내부 데이터 멤버를 가질 수 있지만, 이러한 스레드 객체에 대한 참조를 가지고 (또는 얻을 수있는) 사람에 액세스 할 수 있습니다. 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을의 본질은이 같은 것입니다. 그래서 각 스레드에 대해 로컬입니다.
의도적으로 각 스레드 의미와 관련이 있습니까? 스레드 자체가 바로 객체입니까? 따라서 실제로 스레드와 관련된 것은 스레드 객체와 관련이 있음을 의미합니까? – Ajay
@Ajay : 예. ThreadLocal 인스턴스는, Thread 오브젝트에 부속 세미 데이터 구조를 개입시켜 Thread 오브젝트에 관련 지을 수 있습니다. "package private"멤버 참조 Thread.threadLocals and Thread.inherittableThreadLocals –
@Stephen : Thread 클래스를 사용하는 것에 비해 threadLocal을 사용하면 어떤 차이가 있습니다. – Ajay
ThreadLocals을의 장점은 일반 바닐라 스레드 ... 또는 스레드의 서브 클래스에서 실행 방법으로 사용할 수 있다는 것입니다. 스레드 주민이 스레드의 사용자 지정 하위 클래스의 구성원으로 구현해야하는 경우
는 대조적으로, 당신이 할 수없는 많은 일들이 있습니다. 예를 들어, 기존의 바닐라 스레드 인스턴스에서 메소드를 실행해야하는 경우 응용 프로그램에 문제가 발생할 수 있습니다. 즉 응용 프로그램 작성자가 작성하지 않았으며 수정할 수없는 일부 라이브러리 코드로 작성된 인스턴스.
의 ThreadLocal는 webapplications에 매우 유용합니다. 전형적인 패턴은 웹 요청 처리 (대개 서블릿 필터에서) 상태가 ThreadLocal 변수에 저장된다는 것입니다. 요청에 대한 모든 처리가 1 스레드에서 수행되기 때문에 요청에 참여하는 모든 구성 요소는이 변수에 액세스 할 수 있습니다.
이 문제 영역은 위키 백과 entry about입니다. 우리 환경에서는 대개 로컬 요청을 요청하는 데 사용됩니다. 서버 측에서는 요청이 대부분 단일 스레드에 의해 처리됩니다. 일을 로컬로 유지하려면 데이터를 넣어야합니다 (예 : 스레드 로컬 변수의 세션 데이터 이 데이터는 다른 요청 (스레드)에서 볼 수 없으므로 다른 요청과 동기화 할 필요가 없습니다.
잊지 마세요. 이 아닌 자바 API 구조가 있습니다.은 thread safe합니다. DateFormat. DateFormat의 정적 인스턴스는 서버 측에서 작동하지 않습니다.
사실, 잠금 및 모니터로 처리하는 것보다 자신의 개인 데이터 복사본을 사용할 때 멀티 스레드 프로그래밍을 처리하는 것이 더 쉽습니다.
당신은 스레드를 확장하는 클래스의 인스턴스가 하지 실제 Java 스레드와 같은 일이 것을 깨닫게해야 당신의 코드를 실행하고 실행하는 "실행 포인터"로 상상 할 수 ().
이러한 클래스의 인스턴스는으로 Java 스레드를 나타내며 (예 : 인터럽트)이를 처리 할 수는 있지만 일반 객체 일 뿐이며 그 구성원은 보유 할 수있는 모든 스레드에서 액세스 할 수 있습니다 객체에 대한 참조입니다 (즉 not hard).
물론 멤버를 비공개로 유지하고이 멤버가 호출 된 run()
또는 메서드 (공용 메서드는 다른 스레드에서도 호출 할 수 있음)에서만 사용되도록 할 수는 있지만 오류가 발생하기 쉽고 그렇지 않은 것입니다. 더 복잡한 시스템에서 실제로 쓰레드 하위 클래스에 데이터를 보관하고 싶지는 않습니다. 실제로는 스레드를 서브 클래스 화하지 않고 대신 Runnable을 사용하는 것이 좋습니다.
ThreadLocal은 스레드 당 데이터가 일 수없는 간단하고 유연한 방법으로 다른 스레드에서 동시에 액세스 할 수 없습니다. 많은 노력이나 설계상의 타협이 필요하지 않습니다.
여기에 StaticClass 란 무엇입니까? 스레드를 확장하는 클래스? – Ajay
StaticClass는 ThreadLocal 객체를 가져 오는 편리한 방법입니다. 예제를 수정하여 StaticClass에 대한 코드를 포함시킵니다. – leonm
나는 그것이 항상 더 우아하다고 말하지 않을 것이지만, 더 편리하다. –