Подтвердить что ты не робот

Java ThreadLocal static?

Установка значения в потоке Локальный:

//Class A holds the static ThreadLocal variable.

    Class A{

    public static ThreadLocal<X> myThreadLocal = new ThreadLocal<X>();             
    ....
    }


//A Class B method sets value in A static ThreadLocal variable 
    class B{
    {
         public void someBmethod(){
             X x = new X();
             A.myThreadLocal.set(x);
         }
    }


//Class C retrieves the value set in A Thread Local variable.

    Class C {

    public void someCMethod(){
         X x = A.myThreadLocal.get();
    }
    ...
    }

Quesiton:
Предположим, что это веб-приложение, и выполняются потоки: B.someBMethod, C.someCMethod в этом порядке.

Несколько потоков, выполняющих B someBMethod, завершат обновление SAME статической переменной ThreadLocal myThreadLocal, тем самым опережая саму цель переменной ThreadLocal. (Использование static для ThreadLocal - это то, что рекомендуется в соответствии с документацией.)

C someCMethod при извлечении значения из ThreadLocal может не получить значение, заданное потоком "current".

Что мне здесь не хватает?

4b9b3361

Ответ 1

В соответствии с определением ThreadLocal class

Этот класс предоставляет локальные переменные потока. Эти переменные различаются от их обычных коллег в том, что каждый поток, который обращается к одному (с помощью метода get или set) имеет свой собственный, независимо инициализированный копия переменной. экземпляры ThreadLocal обычно являются частными статические поля в классах, которые хотят связать состояние с потоком (например, идентификатор пользователя или идентификатор транзакции).

Это означает, что 2 потока t1 и t2 выполняет someBMethod(), и они заканчивают установку x1 и x2 (экземпляры X) соответственно. Теперь, когда t1 приходит и выполняет someCMethod(), он получает x1 (который установлен ранее), а t2 получает x2.

Другими словами, безопасно иметь один статический экземпляр ThreadLocal, потому что внутри он делает что-то подобное при вызове set

set(currentThread, value) //setting value against that particular thread

и при вызове get

get(currentThread) //getting value for the thread

Ответ 2

Несколько потоков, выполняющих B someBMethod, завершат обновление SAME. Статическая переменная ThreadLocal myThreadLocal

Да, они работают на одном объекте. Однако важно понимать, что способ ThreadLocal работает в том, что каждый поток имеет свое собственное отдельное значение. Таким образом, если у вас есть десять потоков, записывающих в myThreadLocal, а затем чтение из myThreadLocal, каждый будет видеть правильное (то есть собственное) значение.

Другими словами, неважно, какой класс или объект записывает экземпляр ThreadLocal. Важно то, что поток, в контексте которого выполняется операция.

Ответ 3

Я изучаю исходный код java ,

  • java.lang.Thread Class содержит переменную экземпляр, как показано ниже.

    ThreadLocal.ThreadLocalMap threadLocals = null;

Поскольку переменная threadLocals нестатическая, каждый поток в приложении (т.е. каждый экземпляр класса Thread) будет иметь собственную копию карты threadLocals.

  1. Ключ для этой карты: текущий экземпляр ThreadLocal и значение - это значение, которое вы передаете как аргумент в ThreadLocal.set().

  2. При попытке извлечь значение ThreadLocal.get(), внутренне, оно будет извлекаться из ThreadLocalMap из Current Thread.

В простых терминах вы получаете и устанавливаете значения из/в ваш текущий Тема, не от/до Объект ThreadLocal.

Ответ 4

Несколько потоков, выполняющих B someBMethod, завершат обновление SAME. Статическая переменная ThreadLocal myThreadLocal

Нет, они не будут. Каждый поток имеет свой собственный экземпляр содержащейся переменной типа X.

тем самым нарушая саму цель переменной ThreadLocal

Нет.

Посмотрите еще раз на Javadoc.

Ответ 5

Нет, они этого не сделают. Javadoc:

Эти переменные отличаются от их обычных аналогов тем, что каждый поток, который обращается к одному (посредством метода get или set), имеет свой собственный, независимо инициализированная копия переменной. Примеры ThreadLocal обычно являются частными статическими полями в классах, которые хотят ассоциировать состояние с потоком (например, идентификатор пользователя или идентификатор транзакции).