инструкция
Интервьюер: Расскажите мне о своем понимании ThreadLocal.
Так что же нам ответить? ? ? ? Вы также можете подумать об этом, давайте посмотрим на мышление Зеро;
-
Где используется ThreadLocal?
-
ThreadLocal некоторые подробности!
-
Лучшие практики для ThreadLocals!
-
считать
Где используется ThreadLocal?
Прежде чем обсуждать, где используется ThreadLocal, давайте проясним, что если есть только один поток, то о ThreadLocal говорить не приходится.ThreadLocal используется в многопоточных сценариях! ! !
ThreadLocal можно разделить на 2 категории использования:
- Сохраняйте информацию о контексте потока и получайте ее везде, где она вам нужна! ! !
- Поточно-ориентированная, чтобы избежать некоторых ситуаций, необходимо учитывать потерю производительности, вызванную поточно-ориентированной синхронизацией! ! !
Сохраняйте информацию о контексте потока и получайте ее везде, где она вам нужна! ! !
Благодаря характеристикам ThreadLocal один и тот же поток задается в одном месте и может быть получен в любом последующем месте. Это можно использовать для сохранения информации о контексте потока.
Обычно используется, например, как связать серию последующих запросов для каждого запроса, вы можете использовать ThreadLocal для установки и в любом последующем методе, который должен записывать журналы, получить идентификатор запроса, чтобы получить идентификатор запроса, чтобы связать вместе весь запрос.
Например, управление транзакциями Spring использует ThreadLocal для хранения Connection, так что каждый DAO может получить одно и то же Connection и может выполнять откат транзакций, фиксацию и другие операции.
Примечание:Использование ThreadLocal часто используется в некоторых отличных фреймворках, как правило, мы редко затрагиваем его, но мы затрагиваем больше в следующих сценариях!
Поточно-ориентированная, чтобы избежать некоторых ситуаций, необходимо учитывать потерю производительности, вызванную поточно-ориентированной синхронизацией! ! !
ThreadLocal предлагает новую идею для решения проблемы параллелизма многопоточных программ. Но у ThreadLocal тоже есть ограничения, давайте взглянем на спецификацию Ali:
Чтение и запись данных в ThreadLocal каждым потоком является изоляцией потока и не влияет друг на друга, поэтомуThreadLocal не может решить проблему обновления общих объектов!
Поскольку нет необходимости обмениваться информацией, естественно, нет проблемы конкуренции, что в некоторых случаях обеспечивает безопасность потоков и позволяет избежать потери производительности, связанной с синхронизацией безопасности потоков в некоторых случаях! ! !
Такой сценарий также упоминается в спецификации Ali:
ThreadLocal некоторые подробности!
ThreaLocal использует пример кода:
public class ThreadLocalTest {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
threadLocal.set(i);
System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
threadLocal.remove();
}
}, "threadLocal1").start();
new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
threadLocal.remove();
}
}, "threadLocal2").start();
}
}
Скриншот кода:
Результат запуска кода:
Из текущих результатов видно, что установленное значение threadLocal1 не влияет на threadLocal2!
Thread, ThreadLocalMap, обзор ThreadLocal
Класс Thread имеет переменную атрибута threadLocals (тип ThreadLocal.ThreadLocalMap), что означает, что каждый поток имеет свой собственный ThreadLocalMap, поэтому каждый поток читает и записывает в этот ThreadLocal изолированно и не будет влиять друг на друга.
ThreadLocal может хранить только один объект Object.Если вам нужно хранить несколько объектов Object, вам нужно несколько ThreadLocals! ! !
Как показано на рисунке:
Глядя на картинки выше, наверное, должна быть понятна идея, ключ нашего Entry указывает на ThreadLocal для использованияпунктирная линияУказывает на слабую ссылку, давайте посмотрим на ThreadLocalMap:
Ссылки на объекты Java включают: сильные ссылки, программные ссылки, слабые ссылки и виртуальные ссылки.
Поскольку здесь задействованы слабые ссылки, кратко поясним:
Слабые ссылки также используются для описания несущественных объектов.Когда JVM выполняет сборку мусора, независимо от того, достаточно ли памяти,объект связан только со слабыми ссылками, то он будет переработан.
Когда только ключ Entry в ThreadLocalMap указывает на ThreadLocal, ThreadLocal будет переработан! ! !
После сборки мусора ThreadLocal значение ключа соответствующей записи в ThreadLocalMap станет нулевым, но запись является строгой ссылкой, поэтому объект, хранящийся в записи, не может быть повторно использован, поэтому ThreadLocalMap выполняет дополнительную работу по переработке.
Хоть и делается, но тоже есть риск утечек памяти (не сталкивался, в интернете много подобных сценариев,Так что лучшие практики ThreadLocal будут упомянуты позже! ! !)
Лучшие практики для ThreadLocals!
После сборки мусора ThreadLocal значение ключа соответствующей записи в ThreadLocalMap станет нулевым, но запись является строгой ссылкой, поэтому объект, хранящийся в записи, не может быть повторно использован, поэтому ThreadLocalMap выполняет дополнительную работу по переработке.
Примечание:Много раз мы использовали его в сценарии пула потоков, программа не останавливалась, и поток практически не уничтожался! ! !
Так как жизненный цикл потока очень долгий, если мы зададим очень большой объект Object в ThreadLocal, то хотя set, get и другие методы будут вызываться для дополнительной очистки при определенных условиях, ноПосле сборки мусора ThreadLocal значение ключа соответствующей записи в ThreadLocalMap станет нулевым, но методы set, get и другие в последующем не будут работать.
Поэтому лучше всего активно вызывать метод удаления для очистки, когда мы его не используем.
Еще одно преимущество определения ThreadLocal как статического заключается в том, что, поскольку ThreadLocal имеет сильную ссылку, соответствующий ключ Entry в ThreadLocalMap всегда будет существовать, поэтому при выполнении удаления его можно будет правильно найти и удалить! ! !
Передовой опыт должен быть:
try {
// 其它业务逻辑
} finally {
threadLocal对象.remove();
}
считать
Если вы можете говорить о вышеуказанном содержании во время интервью, я лично считаю, что это очень хорошо, и ответ идеален.ноБыло бы идеально, если бы вы могли сделать следующий ответ.
Для ThreadLocal, когда я просматривал исходный код Netty, я также узнал о FastThreadLocal, xxxxx некоторые столбцы, это обновление.
В моем локальном тесте пропускная способность FastThreadLocal примерно в 3 раза выше, чем у jdkThreadLocal.
Примечание:Поскольку в FastThreadLocal много контента и много умений, я планирую открыть статью, чтобы накрутить его в будущем! ! !
Если вы чувствуете себя вознагражденным после прочтения, пожалуйста, поставьте лайк, подпишитесь и добавьте официальную учетную запись [Ingenuity Zero], чтобы узнать больше захватывающей истории! ! !
)