Уровень класса, уровень экземпляра и локальные ThreadLocals - PullRequest
0 голосов
/ 05 апреля 2020

Я понимаю, как локальные потоки уровня класса имеют смысл. Поскольку мы связаны с потоком, нам нужно, чтобы локальные потоки были общими для разных экземпляров и классов в этом потоке. Поэтому нам нужно сделать их на уровне класса. Если мы хотим совместно использовать потоки для разных экземпляров одного и того же класса, мы можем сделать их private static. Если мы хотим разделить потоки локально между различными классами, мы можем сделать их public static.

Q0. исправьте меня, если я ошибаюсь с вышеприведенным

Мои сомнения касаются локальных (non-static) потоков области действия и локальных (определенных в каком-либо методе) локальных потоков :

Q1. Существует ли какой-либо действительный вариант использования для локальных потоков (non-static) экземпляра с областью действия?
Q2. Есть ли допустимый вариант использования для локальные (определенные внутри какого-то метода) локальные потоки?
Q3. Удаляются ли локальные локальные потоки с областью действия (non-static), когда экземпляр собирается сборщиком мусора?
Q4. Локальные (определенные внутри некоторого метода) локальные потоки удаляются при возврате метода?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

ThreadLocal при правильной реализации как переменная stati c по существу действует как переменная экземпляра для всех потоков, которые имеют к ней доступ. Даже если существует одна переменная ThreadLocal, механизм делает так, чтобы у каждого потока был свой экземпляр значения.

Поэтому

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

Q2. Нет. Поскольку локальная переменная никогда не может иметь доступ более чем к одному потоку, она не будет отличаться от обычной локальной переменной.

Q3. Оболочка ThreadLocal<> становится недоступной, но фактическая переменная все еще содержится в карте потока, как вы правильно сказали. Это приводит к утечке ресурсов / памяти, поскольку ее невозможно очистить, пока поток не остановится.

Q4. Как и в случае с Q3, если вы потеряете ссылку на оболочку, это мгновенная утечка. Если вы назначаете ссылку где-то, это просто странное программирование. Локальная переменная ThreadLocal метода будет крайне тревожным кодом.

Класс - это не то, что вы все равно захотите использовать слишком часто в современном коде (или даже в старом коде), и он не совместим с реактивным программированием , но если вы используете его, использование просто. Одна ThreadLocal наиболее легко реализуется как переменная уровня класса.

1 голос
/ 05 апреля 2020

Q2. Существует ли какой-либо действительный вариант использования для локальных (определенных внутри некоторого метода) локальных потоков?

Во-первых, давайте просто проясним. Если вы говорите «местный Foobar» (для любого class Foobar), то не совсем понятно, о чем вы говорите. Переменные могут быть «уровня класса» (т. Е. static) или «уровня экземпляра» или «локально»; но экземпляр Foobar является , а не переменной. Переменные в программе Java могут только ссылаться на - Foobar экземпляры, которые размещены в куче. Это очень легко, и очень часто иметь в программе более одной переменной, ссылающейся на один и тот же экземпляр.

ThreadLocal - это класс, а экземпляры ThreadLocal - это объекты в куче. На один и тот же объект ThreadLocal может ссылаться переменная static ThreadLocal, а также, в то же время, локальные переменные в одном или нескольких потоках.

Когда вы говорите "локальный ThreadLocal" Вы могли бы говорить о локальной переменной , которая содержит ссылку на экземпляр ThreadLocal, который используется совместно с другими потоками, -OR- , о котором вы могли говорить о ThreadLocal экземпляре, который только ссылается на одну локальную переменную. Второй случай не будет иметь никакого смысла, потому что этот экземпляр не может быть совместно использован несколькими потоками.


Q1. Существует ли какой-либо действительный вариант использования для экземпляра с областью действия (не -stati c) нить локальных?

Может быть и так, но я бы назвал это " запах кода ." (То есть причина внимательно посмотреть на код и посмотреть, можно ли его лучше организовать.) Я лично никогда бы не использовал ThreadLocal в новом коде. Единственный раз, когда я его использовал, это когда я переносил старый однопоточный код в многопоточную систему; и когда я это делал, рассматриваемые переменные всегда были static (то есть, на уровне класса).

I лично старались никогда не использовать static в новом коде, кроме случаев где какая-то функция явно помечена как возвращающая ссылку на «одноэлементный объект».


Q3., Q4. [... когда удаляются экземпляры .. .]?

Экземпляр будет приемлемым , который будет удален, если в программе нет "живой" переменной, которая ссылается на нее. Это может произойти, если единственная переменная, которая ссылается на нее, является локальной переменной некоторой функции, и эта функция возвращает. Второй способ это может произойти, если единственная переменная, которая ссылается на экземпляр, назначена для ссылки на какой-либо другой экземпляр. Третий способ - это если единственные ссылки на него взяты из переменных экземпляра других объектов, и все эти другие объекты сами по себе могут быть удалены.

В большинстве реализаций Java экземпляр не будет немедленно удаляется, когда становится приемлемым для удаления. Фактическое удаление произойдет через некоторое время. Когда, зависит от стратегий, используемых JRE сборщиком мусора и от шаблонов использования объектов программой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...