предисловие
Работайте из дома 💻, не смейте выходить на улицу 🚪, не смейте стричься 💇
Правильно, как и все, после того, как эпидемия закончится, мы будем выглядеть как городской план.
А ты тожеЯ не мыл голову несколько днейкакие?
Ближе к дому~
Эта статья исходит из вопроса в памяти,Реализовать ThreadLocal.
Когда автор впервые столкнулся с этим вопросом, он был очень наивен и написал его за считанные минуты, и обнаружил, что этоМладшая версия, пожалуйста, продолжайте смотреть вниз, чтобы увидеть, были ли вы такими же наивными, как автор.
текст
Низкопрофильная реализация ThreadLocal
В жизни, если вы хотите узнать преимущества чего-либо, что вам следует делать?
Честно говоря, многие этого не понимают. Однако если для сравнения есть аналогичные товары, то преимущества и недостатки очевидны. Далее то же самое, ниже используется авторская младшая версияMyThreadLocalприди и посмотриThreadLocalКаковы преимущества.
На самом деле, когда я увидел этот вопрос, я не внимательно прочитал исходный код ThreadLocal, но у меня все еще было несколько ключевых слов.Map,слабая ссылка, поэтому начал писать версию, общая реализация такая:
public class ThreadLocal<T> {
private Map<Thread, T> threadValMap = Collections.synchronizedMap(new WeakHashMap<>());
public void set(T value) {
threadValMap.put(Thread.currentThread(), value);
}
public T get() {
return threadValMap.get(Thread.currentThread());
}
// remove....
}
Не говорите, я тестировал, и основные функции в порядке.После того, как поток израсходован, ссылка удаляется, GC уведомляется, а значение ключа через некоторое время успешно перерабатывается.
Но открыв исходный код самого ThreadLocal, вы увидите, что дизайн совсем другой.
этоМладшая версияВ чем отличие от обычной версии?
Сравнение двух ThreadLocals
самореализованный, как указано вышеThreadLocal, который я буду называтьMyThreadLocalБар.
MyThreadLocalРеализация очень проста, с помощьюsynchronizedMapМетод реализует синхронизированную слабую ссылку HashMap.
ТакThreadLocalКак внутренняя реализация, я тоже нарисовал эскиз:
Одно из отличий: эффективность
из-заThreadВ оформлении класса есть линияThreadLocal.ThreadLocalMap threadLocals = null;как атрибут.
так,ThreadLocalПри назначении просто отметьтеThreadв классеThreadLocalMapЕсли он пуст, создайте его, если он пуст, и используйте его, если он не пуст.
Два вышеприведенных абзаца описываютMyThreadLocalа такжеThreadLocalПервое отличие:
Младшая версия использует synchronizedMap в качестве контейнера синхронизации.Контейнер синхронизации,а такжеНе параллельный оптимизированный контейнер, исходников естественно многоsynchronized.
ThreadLocal не имеет синхронной операции, но операция выполняется только в собственном текущем потоке, что естественно.закрытие потока. Используя дизайн БД в качестве аналогии, это можно примерно сравнить с этим сценарием:
«Добавьте поле в одну таблицу, и все готово. Вам нужно создать еще одну ассоциативную таблицу, и вы должны обратить внимание на проблемы с транзакциями»..
Конечно, дизайн БД отличается, Таким образом, будет оцениваться производительность, и мы также должны обратить внимание на однопроцессное кодирование.неизменяемый объекта такжезакрытие потока, производительность лучше, чемСинхронизироватьа такжеЗамок.
Второе отличие: ключевой тип карты
Как вы можете видеть на картинке выше,MyThreadLocalКарта напрямую использует Thread в качестве ключа, иThreadLocalКарта использует себя.
Как я упоминал выше, Thread напрямую используется как ключ со слабой ссылкой, и GC также успешно восстанавливается, так в чем же разница?
Разница в том, что только при тестировании выnew Thread();
На практике поток управляется пулом потоков, а повторное использование потока используется в пуле потоков, поэтому на поток всегда будут ссылаться и его нельзя будет подвергнуть сборке мусора, что может привести к утечкам памяти.
ThreadLocalСуществует аналогичная проблема, потому что в большинстве случаев мы будем использоватьstaticСсылка на ThreadLocal, всегда сохраняйте сильную ссылку. К счастью, ThreadLocal предоставляетremoveметод, если разработчик обращает внимание на его вызов после его использования.
наконец
Через младшую версию, написанную автором в то времяMyThreadLocal, вы наверное знаетеThreadLocalГде преимущество, а еще чувствую, что есть деталь поинтереснее:
ThreadLocalMapВнутри HashMap не используется как вспомогательный, а напрямуюРукописный HashMap.
видел в то времяThreadLocalMapКогда я писал код, я думал, что большие ребята хотят показать свои навыки структурирования данных, На самом деле рождение hashMap произошло позже, чем ThreadLocalMap, что было одной из причин его бесполезности.
Подумайте об этом тоже, Дуг Ли и Джош Блох находятся на этом уровне, они все еще показывают свои базовые навыки? …