предисловие
Графический способ пройти таможнюThreadLocal, и надеюсь, что у вас есть некоторыеJVMВ общем, так будет вкуснее.
верю вам, ребята ThreadLocal Как не странно, часто используется в работе, а еще это вопрос высокого дохода, но большинство людей ThreadLocal понимание может быть только"Локальные переменные потока, структура карты", прочитав эту статью, пусть все действительно поймутThreadLocal, чтобы внести помощь в работу каждого, а также сделать интервью более разговорчивым.
план содержания
Эталонный уровень объекта Java
болтать ThreadLocal Прежде чем делать предварительное знание, поговорите оЭталонный уровень объекта Java.
Чтобы сделать программу более гибкой для управления жизненным циклом объекта, отJDK1.2версия запускается,JDKРазделить опорный уровень объекта в порядке убыванияСильная ссылка, мягкая ссылка, слабая ссылка, виртуальностьЧетыре уровня.
Сильная ссылка Сильная ссылка
сильная цитатанаш самый обычный объект, он принадлежитнеперерабатываемые ресурсы, сборщик мусора (именуемый в дальнейшем Г С)Его никогда не вернуть, даже из памяти,J V Mпредпочел бы бросить OutOfMemoryErrorMИсключение, из-за которого программа завершается и не поступает в переработкусильная цитатаобъект.
Мягкая ссылка
если объектмягкая ссылка, то его свойства принадлежатнеобязательный,потому чтодостаточно места в памятина случай, если,G Cне будет перерабатывать его, номеста в памяти мало,G CНайди этотолько мягкие ссылки, объект будет переработан, поэтомумягкая ссылкаобъект подходит какЧувствительный к памяти кэш-объект.
Только объекты толькоSoftReferenceцитата, этомягкий объект опорного уровня, так как объекты могут бытьмногие местацитируется, так что SoftReferenceуказанный объект, который может находиться вВ другом местесильно цитируется.
Слабая ссылка
слабая ссылкаотносительный объектмягкая ссылкаобъект имеетболее короткий жизненный цикл,если толькоG CНайди этотолько слабые ссылки, он будет восстановлен независимо от того, достаточно ли места в памяти, ноG C ЯвляетсяНизкий приоритетпотоки, так что они не обязательно будут обнаружены быстроОбъекты только со слабыми ссылками.
Только объекты толькоWeakReferenceцитата, этоСлабый объект опорного уровня, так как объекты могут бытьмногие местацитируется, так что WeakReferenceуказанный объект, который может находиться вВ другом местесильно цитируется.
PhantomReference
Как подсказывает название,фантомная ссылкаТолько по названию, в отличие от нескольких других цитат,фантомная ссылкаНе определяет время жизни объекта.
если объекттолько фантомные ссылки, то это то же самое, что и без ссылки, и может быть G C Перерабатывать.
Вам хочется это читать?фантомная ссылкаа такжеслабая ссылканет разницы? Их отличия заключаются в следующем
- Когда объекты, на которые ссылаются SoftReference и WeakReference, не перерабатываются, вы можете использовать метод get для получения реального адреса объекта.
- PhantomReference всегда возвращает null, используя метод get
Проще говоря"Реальный адрес объекта нельзя получить через виртуальную ссылку"
резюме
ДжаваSoftReference, WeakReference, PhantomReference, что можно понимать какКласс-оболочка ссылочного уровня объектаИспользуйте соответствующий класс пакета в проекте, чтобы дать ссылочный уровень объекта.
На виртуальной справочной диаграмме естьСправочная очередь, очередь ссылок — это класс-оболочка с уровнем ссылки на объект (SoftReference, WeakReference, PhantomReference) используется, когдаКласс-оболочка ссылочного уровня объектаОбъект указывал после сборки мусора наКласс-оболочка ссылочного уровня объектадобавляется в очередь ссылок,Таким образом, такие операции, как сбор статистики или дополнительная очистка данных, могут выполняться через очередь ссылок.
ThreadLocal
ThreadLocalМногие места называются локальными переменными потока, а некоторые места называются локальным хранилищем потока, что на самом деле означает одно и то же. ThreadLocal создает копию переменной в каждом потоке, и каждый поток может получить доступ к своей собственной внутренней копии переменной.
Что такое ThreadLocal
Threadкласс объявленПеременная-член threadLocals,threadLocalsявляются истинными локальными переменными потока, поэтому каждый Thread имеют свои собственные локальные переменные потока, поэтому локальные переменные потока владеютфункция изоляции потоков, то есть врожденныйпотокобезопасность.
Как видно из приведенного выше рисунка threadLocals Класс переменных-членовThreadLocal.ThreadLocalMap, то есть ThreadLocal который предоставилвнутренний класс,следовательно ThreadЯдро создания, добавления, получения и удаления локальных переменных потока должно быть вокругthreadLocals, так что разработчики тоже рядомthreadLocalsДля реализации функции, для последующего повторного использования, реализация кода также будет инкапсулирована и повторно использована, иThreadLocalЭто класс инструментов с локальной переменной потока, который определяется J D K При условии, что функции локальных переменных потока реализованы «из коробки» в интересах большинства разработчиков.
ThreadLocalЧасто используемые методы
- set: установить переменную для текущего потока, текущий ThreadLocal в качестве индекса
- get: получить текущую переменную потока, текущий ThreadLocal в качестве индекса
- InitialValue (метод ловушки должен быть реализован подклассом): Инициализируйте локальную переменную потока в форме загрузки.При выполнении get, если локальная переменная потока окажется нулевой, будет выполнено содержимое InitialValue.
- удалить: очистить индекс ThreadLocal текущего потока и сопоставленные элементы
Один Threaможет иметь несколькоПара ключ-значение ThreadLocal (хранится в структуре ThreadLocalMap),и потому, что ThreadLocalMap зависит от текущегоThread,Threadпри уничтожении ThreadLocalMap также будет уничтожен, поэтому ThreadLocalMap жизненный цикл и Thread связывать.
Теперь подведите итог«Область локальных переменных потока принадлежит всей области действия текущего потока, и поток может использовать локальные переменные потока в нескольких методах», когда вы хотитенекоторые переменныевThread Делитесь несколькими методами и обеспечьте безопасность потоков, а затем смело используйтеThreadLocal(ps: обязательно выясните, используется ли переменная несколькими методами в жизненном цикле потока или она используется несколькими потоками! ).
Исходный код ThreadLocal
Давайте сначала посмотрим на код локальной переменной потока, реализованный классом User.
Существует не так много методов, а именноInitialValue, получить, установить, удалить, а затем проанализируйте исходный код этих методов.
Структура ThreadLocalMap
Чтобы позже иметь лучший опыт анализа исходного кода, необходимо ввести следующееThreadLocalMap, как следует из названия, это Map структуру, но основное содержание этой статьи неMap, так что давайте быстро взглянем на этот фрагмент контента на предыдущей картинке.
Судя по картинке выше, я считаю, что все правы. ThreadLocalMap Структура уже очень ясна, интересно, нашли ли ее какие-нибудь внимательные друзья ThreadLocal был на самом делеслабая ссылкадержать?
Почему на ThreadLocal слабо ссылаются?Это сомнение будет ясно устроено для всех позже, и последнее ThreadLocalMap Схема источника.
получить переменную
Действуйте следующим образом
- получить текущий поток
- Получить локальную переменную текущего потока
- Локальная переменная потока не создана, выполните метод setInitialValue для инициализации и верните значение value
- Если локальная переменная потока существует, ThreadLocal вычисляет индекс для получения Entry из локальной переменной потока.Если Entry имеет значение null, выполните метод setInitialValue для инициализации и возврата значения, в противном случае получите значение через Entry и верните его.
метод начального значения
Действуйте следующим образом
- Запускается методом get
- Выполнить инициализацию и получить значение
- получить текущий поток
- Получить локальную переменную текущего потока
- Если текущая локальная переменная потока существует, ThreadLocal вычисляется как значение карты параметров индекса, в противном случае создайте локальную переменную потока, а затем выполните последующие операции установки.
- возвращаемое значение
установить заданную переменную
Действуйте следующим образом
- получить текущий поток
- получить локальную переменную потока
- Локальная переменная не пуста, текущий ThreadLocal устанавливает сопоставленное значение для индекса, в противном случае создайте локальную переменную потока, а затем выполните последующие операции установки
удалить четкую переменную
Действуйте следующим образом
- Получить массив записей
- Текущий ThreadLocal вычисляет индекс
- Получить элемент Entry в соответствии с индексом (если он не попал в первый раз, он будет зацикливаться до нуля)
- Очистить элемент ввода
резюме
Исходный код очень простой, ядра триКласс инструмента локальной переменной потока ThreadLocal (одновременно с индексом), базовые элементы Entry (состоящие из класса-оболочки ThreadLocal со слабой ссылкой и значения), контейнер массива Entry, процесс здесь очень ясен,ThreadLocalЧтобы вычислить индекс массива, используйте ThreadLocal а также value строить из Entry элемент, наконец, вставьте Entry В контейнере, я считаю, каждый может написать это.
Зачем использовать слабые ссылки
Зачем Entry средняя пара ThreadLocal Использовать слабые ссылки? Риторический вопрос, что произойдет, если вы используете сильные ссылки?
Функция кода на картинке выше состоит в том, чтобы все поняли, почему используются слабые ссылки, и такой код не появится в общей разработке (Действительно оказалось, этот программист боится, что его потащат в жертву небу).
Вернемся к теме, давайте быстро разберем код, сначала ThreadContextTest хранить частные статические переменные ThreadLocal,а также ThreadContextTest запретитьсоздавать экземпляр, затем выполните статический метод run Запустите статический блок как ThreadLocal Установите пользовательскую переменную и удалите ThreadLocal Сильная ссылка, в это время локальная переменная текущего потока имеетВходной элемент.
Вопрос в том, как получить Entryэлемент, согласно нормальному потоку,ThreadLocalвоплощать в жизнь get метод,getбудет использовать текущий ThreadLocal Вычислите индекс и, наконец, получитеВходной элемент, но текущая проблема показана ниже.
Мы не знаем, что такое ключ, как получить значение карты, по той же причине нет входа для его полученияThreadContextTest.ThreadLoca, естественно нет возможности получить отображениеВходной элемент.
используется в дизайнеMapструктура хранит данные, но не может передатьkeyполучитьvalue, такая конструкция заведомо неразумна, а посколькуключ, значениеvalue является строгой ссылкой, что приводит к G C Невозможно переработать, что приводит к переполнению памяти.
Итак, для этого неразумного сценария дизайна J D K оптимизирован, да Entry середина ThreadLocal Использование слабых ссылок, когда G C Когда обнаружится, что он имеет только слабые ссылки, он будет переработан.
Смысл удаления
Это еще не конец, на нем остался хвостик, это все знают Entry средняя пара ThreadLocal Используется слабая ссылка, но значение является сильной ссылкой.Если возникает необоснованный сценарий, упомянутый выше, значение значения не может быть очищено, и в конечном итоге память переполняется.
фактическиvalueтак каксильная цитатадизайн разумный, если используетсямягкая или слабая ссылка,есть большая проблема,программа запускается и запускается и вдруг получает ноль,подсчитано,что надо маму ругать,так что для решения проблемы переполнения памятиJ D Kпоставкаremoveметод, который дает разработчикам возможность вручную очистить всеВходной элемент, чтобы предотвратить переполнение памяти.
Помните, что я сказал раньше? Время жизни локальной переменной потока такое же, какобвязка нитью, жизненный цикл общего потока относительно короткий, когда поток заканчивается, локальная переменная потока естественно уничтожается,мягкая ссылкаа также remove Будет ли это немного лишним?
Бизнес быстро меняется.В большинстве случаев жизненный цикл потоков относительно короткий, но бизнес-сценарии также могут привести к жизненному циклу потоков.дольше, а может и нитьБесконечная петляВыполнение, это вещи, которые вы не можете ожидать.Как только число подходит, легко переполнить память, поэтому я лично рекомендую очищать ThreadLocal вовремя после использования по следующим причинам.
- Сценарии потоков с длительным жизненным циклом
- Сценарий потока бесконечного цикла
- Сценарий пула потоков (поскольку пул потоков может повторно использовать потоки, а фреймворк, используемый компанией, может настраивать пул потоков, вы не можете гарантировать, что это поможет вам удалить в пуле потоков)
нытье ворчание
Прежде всего, поздравляю всех с наступающим Новым годом и всего самого наилучшего! ! ! Двухнедельная печеночная статья блогера, хоть цикл и длинноват, но качество гарантировано, да и кодировать текст непросто.Если вы считаете, что эта статья вам полезна, поделитесь ею с друзьями, а поставить Axing «Нравится + Избранное», это очень важно для Ah Xing, спасибо, и обниму вас, увидимся в следующий раз!
обо мне
Официальный аккаунт: "Program Ape A Star" посвящен техническим принципам, исходному коду и технологиям вывода с помощью диаграмм. Здесь мы будем делиться качественными оригинальными статьями об операционных системах, компьютерных сетях, Java, распределенных системах, базах данных и т. д., а также с нетерпением ждем вашего внимания.