Threadlocal java что это

Введение в ThreadLocal на Java

Краткое и практическое руководство по использованию ThreadLocal для хранения данных, специфичных для потоков, в Java.

1. Обзор

2. ThreadLocal API

Конструкция Threadlocal позволяет нам хранить данные, которые будут доступны только конкретному потоку .

3. Хранение пользовательских данных на карте

Давайте рассмотрим программу, которая должна хранить пользовательские Контекстные данные для каждого заданного идентификатора пользователя:

Затем мы сохраняем этот контекст в Concurrenthashmap с ключом userId :

Мы можем легко протестировать ваш код, создав и запустив два потока для двух разных идентификаторов пользователей и утверждая, что у нас есть две записи в userContextPerUserId map:

4. Хранение пользовательских данных в ThreadLocal

Метод run() извлекает пользовательский контекст и сохраняет его в переменной ThreadLocal с помощью метода set() :

Мы можем проверить это, запустив два потока, которые будут выполнять действие для данного userId :

После запуска этого кода мы увидим на стандартном выходе, что ThreadLocal был установлен для данного потока:

5. ThreadLocals и пулы потоков

ThreadLocal предоставляет простой в использовании API для ограничения некоторых значений для каждого потока. Это разумный способ достижения потокобезопасности в Java. Однако мы должны быть особенно осторожны, когда мы используем ThreadLocal s и пулы потоков вместе.

Чтобы лучше понять возможную оговорку, давайте рассмотрим следующий сценарий:

Это может привести к неожиданным последствиям в сильно параллельных приложениях.

5.1. Расширение ThreadPoolExecutor

Как оказалось, можно расширить класс ThreadPoolExecutor и предоставить пользовательскую реализацию крючка для методов beforeExecute() и afterExecute () . Пул потоков вызовет метод beforeExecute() перед запуском чего-либо с использованием заимствованного потока. С другой стороны, он вызовет метод afterExecute() после выполнения нашей логики.

Поэтому мы можем расширить класс ThreadPoolExecutor и удалить данные ThreadLocal в методе afterExecute() :

6. Заключение

Источник

Русские Блоги

Подробное объяснение ThreadLocal в Java

Подробное объяснение ThreadLocal в Java

1. Введение в ThreadLocal

ThreadLocal предоставляется пакетом JDK. Он предоставляет локальные переменные потока. Если вы создаете переменную ThreadLocal, каждый поток, который обращается к этой переменной, будет иметь копию этой переменной. В фактической многопоточной операции операция является его собственной локальной памятью. Переменные в, что позволяет избежать проблем с безопасностью потоков, как показано на следующем рисунке.

Во-вторых, ThreadLocal прост в использовании

В следующем примере запускаются два потока, значение локальной переменной устанавливается в каждом потоке, а затем вызывается метод печати для печати значения текущей локальной переменной. Если вы вызовете метод удаления локальной переменной после печати, переменная в локальной памяти будет удалена, код выглядит следующим образом

Вот результат после бега:

В-третьих, принцип реализации ThreadLocal

Ниже представлена ​​структура диаграммы классов ThreadLocal, как видно из рисунка: В классе Thread есть две переменные threadLocals и inheritableThreadLocals, обе из которых являются переменными типа ThreadLocalMap во внутреннем классе ThreadLocal. Мы можем обнаружить, что она фактически похожа на одну, посмотрев на внутреннюю ThreadLocalMap. HashMap. По умолчанию эти две переменные в каждом потоке равны нулю., Они создаются только тогда, когда поток вызывает методы set или get ThreadLocal в первый раз (мы рассмотрим исходный код этих двух методов позже). Кроме того, что отличается от того, что я думаю, это то, что локальные переменные каждого потока хранятся не в экземпляре ThreadLocal, а в переменной ThreadLocals вызывающего потока (как упоминалось ранее, эта переменная является переменной класса Thread ). Другими словами, локальные переменные типа ThreadLocal хранятся в определенном пространстве потока, что эквивалентно оболочке инструмента, которая загружает локальные переменные. Значение добавляется в threadLocals вызывающего потока с помощью метода set. Когда вызывающий поток вызывает метод get Возможность извлекать переменные из своего потокаLocals. Если вызывающий поток не завершается, локальная переменная всегда будет храниться в его threadLocals, поэтому, когда локальная переменная не используется, необходимо вызвать метод remove, чтобы удалить неиспользуемую локальную переменную из threadLocals. Ниже мы рассмотрим методы набора, получения и удаления ThreadLocal, чтобы увидеть, как на самом деле работает ThreadLocal.

Читайте также:  мне нравится мама друга что делать

1, установить исходный код метода

В приведенном выше коде (2) вызовите метод getMap, чтобы получить threadLocals, соответствующий текущему потоку (см. Приведенную выше иллюстрацию и текстовое описание), код метода выглядит следующим образом

Метод createMap не только создает threadLocals, но также добавляет значение локальных переменных, которые будут добавлены в threadLocals.

2, получить исходный код метода

В реализации метода get сначала получите текущий вызывающий поток, если threadLocals текущего потока не равен нулю, напрямую верните значение локальной переменной, привязанной к текущему потоку, в противном случае выполните метод setInitialValue для инициализации переменной threadLocals. В методе setInitialValue, аналогично реализации метода set, он предназначен для определения того, имеет ли значение переменной threadLocals текущего потока значение null. Если это так, добавьте локальную переменную (на этот раз инициализируется, поэтому добавленное значение равно null), в противном случае создается переменная threadLocals, то же Добавленная стоимость равна нулю.

3, реализация метода удаления

Метод remove определяет, является ли переменная threadLocals, соответствующая текущему потоку, нулевой, и, если она не равна нулю, напрямую удаляет переменную threadLocals, указанную в текущем потоке.

В-четвертых, ThreadLocal не поддерживает наследование.

Пять, класс InheritableThreadLocal

Упомянутый выше класс ThreadLocal не может предоставлять дочерним потокам доступ к локальным переменным родительского потока, в то время как класс InheritableThreadLocal может это делать. Исходный код этого класса выглядит следующим образом

Как видно из приведенного выше кода, класс InheritableThreadLocal наследует класс ThreadLocal и переписывает три метода childValue, getMap и createMap. Когда вызывается метод createMap (метод должен вызываться, когда карта, полученная, когда текущий поток вызывает метод set, имеет значение null), он создает наследуемыйThreadLocal вместо threadLocals. Таким же образом метод getMap возвращает не threadLocals, а inheritableThreadLocal, когда текущий вызывающий поток вызывает метод get.

Давайте посмотрим, когда будет выполнен переписанный метод childValue и как разрешить дочернему потоку получить доступ к значению локальной переменной родительского потока. Начнем с класса Thread

В методе инициализации сначала (1) получает текущий поток (родительский поток), а затем (2) оценивает, имеет ли свойство inheritableThreadLocals текущего родительского потока значение null, а затем вызывает createInheritedMap для создания нового с наследуемымиThreadLocals родительского потока в качестве параметра конструктора. Затем дочернему потоку присваивается переменная ThreadLocalMap. Ниже приведены метод createInheritedMap и метод построения ThreadLocalMap.

В конструкторе присвойте значение переменной-члену inheritableThreadLocals родительского потока новому объекту ThreadLocalMap. НаследуемыеThreadLocals назначаются дочернему потоку после возврата. Короче говоря, класс InheritableThreadLocals сохраняет локальные переменные в переменной inheritableThreadLocals определенного потока, переопределяя методы getMap и createMap. Когда поток устанавливает переменную с помощью метода set или get экземпляра InheritableThreadLocals, он создает переменную inheritableThreadLocals текущего потока. Когда родительский поток создает дочерний поток, конструктор в ThreadLocalMap копирует переменные из наследуемогоThreadLocals родительского потока в переменную inheritableThreadLocals дочернего потока.

В-шестых, из ThreadLocalMap, чтобы увидеть проблему утечки памяти из-за неправильного использования ThreadLocal

1. Основные концепции

①Сильная ссылка: тип ссылки по умолчанию в Java. Если объект имеет сильную ссылку, он не будет GC, пока ссылка все еще существует.

②Программная ссылка: Короче говоря, если объект имеет слабую ссылку, объект не будет GC до появления OOM в JVM (то есть, если память будет использована в достаточной степени); объект будет GC только когда памяти JVM недостаточно. Мягкая ссылка используется вместе с очередью ссылок. Если объект, на который ссылается мягкая ссылка, переработан, ссылка будет добавлена ​​в связанную с ним очередь ссылок.

Читайте также:  Trashbin miui что это

2. Проанализируйте внутреннюю реализацию ThreadLocalMap.

Выше мы знаем, что ThreadLocalMap на самом деле является массивом Entry, Давайте посмотрим на этот внутренний класс Entry

Учтите, что эта переменная ThreadLocal не имеет других сильных зависимостей. Если текущий поток все еще существует, потому что ключ в ThreadLocalMap потока является слабой ссылкой, слабая ссылка на переменную ThreadLocal в ThreadLocalMap текущего потока будет повторно использована во время gc, но соответствующее значение Он все еще существует, что может вызвать утечку памяти (потому что в это время ThreadLocalMap будет иметь элементы записи, ключ которых равен нулю, но значение не равно нулю).

Сводка: ключ Entry в THreadLocalMap использует слабую ссылку на объект ThreadLocal. Если нет другого места, где можно было бы полагаться на ThreadLoca, объект ThreadLocal в ThreadLocalMap будет переработан, но соответствующий не будет переработан. Это возможно на карте. Есть элементы, в которых ключ равен нулю, но значение не равно нулю. Это требует, чтобы метод удаления был вызван вовремя после использования, чтобы избежать утечки памяти.

Источник

Солянка

За последнее время скопилось несколько различных мыслей. Надеюсь, какие-то из них покажутся интересными.
Итак, в солянке:

1. Java: что такое ThreadLocal и InheritableThreadLocal
2. Palm Pre: личные впечатления
3. Android: как развернуть сервер на телефоне
4. Интерфейсы: концепция страницы «про нас»
5. Книжки: впечатления от Pragmatic Thinking and Learning: Refactor Your Wetware

1. Java: что такое ThreadLocal и InheritableThreadLocal

2. Palm Pre: личные впечатления

Не так давно мне удалось порабоать с Palm Pre. Palm Pre — это новый телефон от Palm. iPhone killer. На самом деле, телефон оказался очень неплохим. Во-первых, добротно сделаная операционная система: очень приятый интерфейс, особенно радует грамотно реализованый мултитач. Во-вторых, отличный набор тулзов для разработчика. Для тех, кто хочет глубоко интегрироваться с системой (на уровне OS) предоставляется SDK и набор хедеров. Для разработчиков обычных аппов — неплохой набор тулзов и эмулятор. Приложения представляют собой довольно интересный гибрид веб-приложений и нативных методов. Платформа сделана очень developer-friendly.
Говорят, что все в Palm очень гордятся продуктом. С моей точки зрения, есть чем гордится.

3. Android: как развернуть сервер на телефоне

while ( isRunning )
<
// Ждём нового клиента
final Socket socket = serverSocket.accept();

Пожалуй, стоит лишь предупредить разработчиков об аккуротном закрытие сокетов, Socket::isClosed() не всегда адекватно выражает состояние соединения.

4. Интерфейсы: концепция страницы «про нас»

Вот такая идея: на странице «про нас» поместить общую фотографию всех разработчиков. Обводишь мышкой лицо разработчика, а слева появляется информация о том, чем человек занимался. Ну и, может, форма отправки сообщения. Что-то такое:

5. Книжки: впечатления от Pragmatic Thinking and Learning: Refactor Your Wetware

Основная идея книжки: те, кто занимается умственным трудом должны развивать не только «software» мозга, но и «hardware» («wetware», в случае человеков). Постоянно учиться, менять сферы деятельности, запоминать новую информацию, не лениться быть любопытным. Эти активности помогут мозгу не прекращать создавать новые нейронные связи и менять существующие.
Более того, автор продвигает интересный тезис: развите мозга может не прекращаться в определённом возрасте. То есть, при желании, с возрастом можно не растерять остроту мышления и способность учиться новому. Напротив, можно развить мозг так, что он будет эффективно усваивть и обрабатывать информацию.
Очень рекомендую: Pragmatic Thinking and Learning: Refactor Your Wetware.

Читайте также:  рхту телефон приемной комиссии 2021

Надеюсь, в моей солянке оказалось достаточно копчёностей, и читатель получил от неё удовольствие.

Источник

Параллелизм Java — класс ThreadLocal

Класс ThreadLocal используется для создания локальных переменных потока, которые могут быть прочитаны и записаны только одним потоком. Например, если два потока обращаются к коду, имеющему ссылку на одну и ту же переменную threadLocal, то каждый поток не увидит никаких изменений в переменной threadLocal, выполненных другим потоком.

ThreadLocal Методы

Ниже приведен список важных методов, доступных в классе ThreadLocal.

Возвращает значение в копии текущего потока этой локальной переменной потока.

Защищенный T initialValue ()

Возвращает «начальное значение» текущего потока для этой локальной переменной потока.

public void remove ()

Удаляет значение текущего потока для этой локальной переменной потока.

открытый набор пустот (значение T)

Устанавливает копию текущего потока этой локальной переменной потока в указанное значение.

Возвращает значение в копии текущего потока этой локальной переменной потока.

Защищенный T initialValue ()

Возвращает «начальное значение» текущего потока для этой локальной переменной потока.

public void remove ()

Удаляет значение текущего потока для этой локальной переменной потока.

открытый набор пустот (значение T)

Устанавливает копию текущего потока этой локальной переменной потока в указанное значение.

пример

Следующая программа TestThread демонстрирует некоторые из этих методов класса ThreadLocal. Здесь мы использовали две переменные счетчика, одна из которых является нормальной переменной, а другая — ThreadLocal.

Это даст следующий результат.

Выход

Вы можете видеть, что значение счетчика увеличивается каждым потоком, но threadLocalCounter остается 0 для каждого потока.

Источник

Java.lang.ThreadLocal класс в Java

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

Конструктор:
ThreadLocal (): это создает локальную переменную потока.
Методы:

// Java-код, иллюстрирующий методы get () и set ()

public class ThreadLocalDemo <

public static void main(String[] args)

ThreadLocal gfg_local = new ThreadLocal ();

ThreadLocal gfg = new ThreadLocal ();

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg.get());

// Java-код, иллюстрирующий метод remove ()

public class ThreadLocalDemo <

public static void main(String[] args)

ThreadLocal gfg_local = new ThreadLocal ();

ThreadLocal gfg = new ThreadLocal ();

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg.get());

// возвращает значение текущего потока

System.out.println( «value = » + gfg_local.get());

// Java-код, иллюстрирующий метод initialValue ()

class NewThread extends Thread <

private static ThreadLocal gfg = new ThreadLocal()<

protected Object initialValue()<

return new Integer(question—);

private static int question = 15 ;

for ( int i = 0 ; i 2 ; i++)

public class ThreadLocalDemo <

public static void main(String[] args)

NewThread t1 = new NewThread( «quiz1» );

NewThread t2 = new NewThread( «quiz2» );

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Источник

Образовательный портал
Sr.No. Метод и описание
1