Wątek jest jednostką wykonawczą, więc wiele wątków może wykonywać ten sam kod w tym samym czasie. Jeśli wiele wątków zostanie wykonanych na obiekcie/instancji w tym samym czasie, udostępnią zmienne instancji. Każdy wątek będzie miał własne zmienne lokalne, ale trudno jest je udostępniać w obiektach bez przekazywania parametrów.
Najlepiej wyjaśnić to na przykładzie. Powiedzmy, że masz Servlet, który pobiera zalogowanego użytkownika, a następnie wykonuje pewien kod.
doGet(HttpServletRequest req, HttpServletResponse resp) {
User user = getLoggedInUser(req);
doSomething()
doSomethingElse()
renderResponse(resp)
}
Co się stanie, jeśli metody doSomething() będą wymagać dostępu do obiektu użytkownika? Nie można uczynić obiektu użytkownika instancją lub zmienną statyczną, ponieważ każdy wątek będzie używał tego samego obiektu użytkownika. Można przekazać obiekt użytkownika wokół jako parametr, ale ten szybko staje się plączą i przecieki obiektów użytkownika w każdym wywołaniu metoda:
doGet(HttpServletRequest req, HttpServletResponse resp) {
User user = getLoggedInUser(req);
doSomething(user)
doSomethingElse(user)
renderResponse(resp,user)
}
Bardziej eleganckim rozwiązaniem jest umieszczenie obiektu użytkownika w ThreadLocal
doGet(HttpServletRequest req, HttpServletResponse resp) {
User user = getLoggedInUser(req);
StaticClass.getThreadLocal().set(user)
try {
doSomething()
doSomethingElse()
renderResponse(resp)
}
finally {
StaticClass.getThreadLocal().remove()
}
}
teraz każdy kod, który wymaga obiektu użytkownika w każdej chwili może zdobyć go przez wyodrębnianie z wątku lokalnej, bez konieczności uciekania się do tych nieznośnych dodatkowych parametrów:
User user = StaticClass.getThreadLocal().get()
Jeśli użyjesz tego podejścia, pamiętaj, aby ponownie usunąć obiekty w bloku finally. W przeciwnym razie obiekt użytkownika może się kręcić w środowiskach korzystających z puli wątków (np. Serwer aplikacji Tomcat).
Edycja: Kod dla klasy statycznej
class StaticClass {
static private ThreadLocal threadLocal = new ThreadLocal<User>();
static ThreadLocal<User> getThreadLocal() {
return threadLocal;
}
}
Co to jest StaticClass? Klasa, która rozszerza wątek? – Ajay
StaticClass to po prostu wygodny sposób na uzyskanie obiektu ThreadLocal. Będę edytować przykład, aby dołączyć kod dla StaticClass. – leonm
Nie powiedziałbym, że zawsze jest bardziej elegancki, ale jest bardziej celowy –