причина
Я недавно вошел в разработку команды проекта.Когда я изредка читал чужой код, то видел следующие комментарии.
Примечание. ThreadLocalUtil использует внутреннюю статическую переменную ThreadLocal.Я был совершенно озадачен, когда впервые увидел это, и я не знаю, почему он так сказал. Когда мой коллега объяснил мне причину, я внезапно стал просветленным. Подумайте об этом, в нашей работе, если мы не обращаем внимания, легко игнорировать эту проблему. Прежде чем объяснять эту проблему, давайте сначала рассмотрим ThreadLocal.
ThreadLocal
ThreadLocal предоставляет локальные переменные потока и создает отдельную копию переменной для каждого потока, так что в многопоточной среде, поскольку каждый поток имеет отдельную переменную, не будет проблем параллелизма, вызванных совместным использованием переменных. Конечно, связанные проблемы мы можем использовать механизм синхронизации для решения этой проблемы.
Разница между механизмом синхронизации и ThreadLocal
Используя механизм синхронизации, многопоточная среда совместно использует одну и ту же переменную, что требует от нас отображать блокировку при ее использовании, чтобы гарантировать, что только один поток может использовать переменную одновременно, что эквивалентно принятию временной стратегии взамен. для безопасности потоков.
С ThreadLocal каждый поток имеет свою собственную независимую копию переменной, что эквивалентно принятию пространственной стратегии в обмен на безопасность потока.
Давайте посмотрим на разницу между двумя методами из кода. Теперь, если нам нужен текущий класс инструмента времени, следующим образом:
private final static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String getDateStr(Date date) {
return format.format(date);
}
Глядя на приведенную выше демонстрацию, мы можем легко увидеть, что приведенный выше метод не является потокобезопасным, поскольку SimpleDateFormat не является потокобезопасным, поэтому метод getDateStr не является потокобезопасным.
Теперь преобразуем его с помощью синхронизации.
private final static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static synchronized String getDateStrSync(Date date) {
return format.format(date);
}
Таким образом, блокировка отображения используется, чтобы избежать безопасности потоков в многопоточной среде. Но этот подход может повлиять на эффективность в ситуациях с высокой степенью параллелизма.
Следующее использует ThreadLocal для его преобразования.
private final static ThreadLocal<SimpleDateFormat> formatLocal = new ThreadLocal<SimpleDateFormat>() {
protected synchronized SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
public static String getDateByLocal(Date date){
return formatLocal.get().format(date);
}
Используйте ThreadLocal, чтобы превратить общие переменные в эксклюзивные переменные, чтобы обеспечить безопасность потоков. Но это решение увеличивает накладные расходы на создание объектов.
Подводя итог, необходимо выбрать два вышеуказанных метода в сочетании с текущим бизнес-методом.
После разговора о ThreadLocal давайте взглянем на модель потоков dubbo.
даббо резьбовая модель
По умолчанию dubbo использует одно длинное соединение и пул потоков для обработки вызовов.
По умолчанию применяется стратегия отправки Dispatcher=all, и все сообщения отправляются в пул потоков, включая запросы, ответы, события подключения, события отключения, тактовые импульсы и т. д. По умолчанию пул потоков настроен как пул потоков фиксированного размера.Поток создается при запуске, а не закрывается и удерживается все время. По умолчанию 100 потоков.
Анализ использования ThreadLocal в Dubbo
При использовании ThreadLocal в Dubbo, если приняты настройки по умолчанию, каждый раз, когда завершаются вызовы Dubbo, поток ответа обработки Dubbo не будет уничтожен, а будет возвращен в пул потоков. Как видно из исходного кода ThreadLocal, значение, которое мы устанавливаем каждый раз, действительно будет существовать в переменной ThreadLocalMap в Thread.
Это приводит к тому, что в следующий раз, если Dubbo продолжит использовать этот поток для обработки ответа, поток может вызвать значение, установленное в ThreadLocal в последнем ответе. Это вызывает утечки памяти, а также может привести к бизнес-исключениям. На самом деле, это дело не только в Dubbo, но и в веб-проектах, пока используется пул потоков, может случиться.
Резюме локального потока
Используя Threadlocal, нам нужно обратить внимание на несколько моментов:
- Использование Threadlocal должно быть таким же, как и использование связанных потоков.Вам необходимо явно вызвать его метод удаления в конце, чтобы очистить установленное значение для предотвращения утечек памяти.
- Вы не можете использовать Threadlocal для передачи всех параметров вверх и вниз в методе, что приведет к невидимой связи, а связанный код непросто поддерживать.
- В условиях высокого параллелизма мы можем использовать Threadlocal вместо блокировок синхронизации, чтобы повысить соответствующую производительность.
Ссылка на ссылку
- [Dead Java Concurrency] - Углубленный анализ ThreadLocal
- Давайте поговорим о безопасности потоков в Spring
- Элегантно используйте ThreadLocal для передачи параметров
- Ууууу.Поставь арлингтон-терьер.com/Java-thread…
- woo woo woo.cn блог на.com/детская болезнь/…
- даббо резьбовая модель
- How to shoot yourself in foot with ThreadLocals
Если вы считаете, что это хорошо, пожалуйста, поставьте автору большой палец вверх~ Спасибо.
Читатели, которым понравилась эта статья, добро пожаловать в долгое нажатие, чтобы следить за сообщением программы номера подписки ~ позвольте мне поделиться программой с вами.