Java 200+ вопросов для собеседования дополняют модуль ThreadLocal

интервью Java
Java 200+ вопросов для собеседования дополняют модуль ThreadLocal

Эта статья является предыдущей статьей«Наиболее 200 самых распространенных вопросов на собеседовании по Java»Первый дополнительный модуль .

Давайте добиваться прогресса каждый день, Лао Ван поможет вам создать самый полный список интервью по Java и довести одну вещь до крайности.

1. Что такое ThreadLocal?

ThreadLocal — это служебный класс переменной копирования локального потока. Он в основном используется для сопоставления частного потока и объекта копирования, хранящегося в потоке. Переменные между каждым потоком не мешают друг другу. В сценариях с высоким уровнем параллелизма могут быть реализованы вызовы без сохранения состояния, и он подходит для операций, в которых каждый поток не разделяет значения переменных.

2. Как работает ThreadLocal?

Принцип ThreadLocal: каждый поток внутренне поддерживает ThreadLocalMap, который представляет собой формат данных Map (ключ, значение).Ключ представляет собой слабую ссылку, то есть сам ThreadLocal, а значение хранит значение переменной потока.

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

Структура данных, как показано на следующем рисунке:

(картинка взята из интернета)

3. Как ThreadLocal разрешает конфликты хэшей?

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

Реализация исходного кода выглядит следующим образом:

/
 * Increment i modulo len.
 */
private static int nextIndex(int i, int len) {
    return ((i + 1 < len) ? i + 1 : 0);
}

/
 * Decrement i modulo len.
 */
private static int prevIndex(int i, int len) {
    return ((i - 1 >= 0) ? i - 1 : len - 1);
}

4. Что такое утечка памяти в ThreadLocal?

ThreadLocal упоминается ключом в Entry как слабая ссылка в ThreadLocalMap, поэтому, если ThreadLocal не имеет внешней сильной ссылки для ссылки на него, ThreadLocal будет переработан в следующей сборке мусора JVM. В настоящее время ключ в записи был переработан, но значение является строгой ссылкой и не будет переработано сборщиком мусора, поэтому, если поток ThreadLocal продолжит работу, значение не будет переработано, а утечки памяти будут происходить.

5. Почему ключ ThreadLocalMap является слабой ссылкой?

Мы знаем, что ключ в ThreadLocalMap — это слабая ссылка, а значение — сильная ссылка, что приведет к проблеме утечек памяти, а зачем нужна такая конструкция, мы обсудим в двух случаях:

  • В ключе используется сильная ссылка: это вызовет проблему. Ссылочный объект ThreadLocal повторно используется, но ThreadLocalMap по-прежнему содержит сильную ссылку на ThreadLocal. Если его не удалить вручную, ThreadLocal не будет повторно использован, что приведет к утечки памяти.
  • Ключ использует слабую ссылку: в этом случае объект ThreadLocal, на который делается ссылка, повторно используется. Поскольку ThreadLocalMap содержит слабую ссылку на ThreadLocal, даже если он не удален вручную, ThreadLocal будет повторно использован. значение будет очищено при следующем вызове ThreadLocalMap set, get, remove.

Сравнивая два приведенных выше случая, мы можем обнаружить, что, поскольку жизненный цикл ThreadLocalMap такой же длинный, как и у Thread, если соответствующий ключ не будет удален вручную, это приведет к утечкам памяти, но использование слабых ссылок может обеспечить дополнительный уровень защита, а слабые ссылки на ThreadLocal не будут приводить к утечке памяти, соответствующее значение будет очищено, когда ThreadLocalMap вызовет set, get, remove в следующий раз, что является лучшим решением.

6. Каковы сценарии применения ThreadLocal?

ThreadLocal подходит для независимых копий переменных, таких как сценарии получения сеанса Hibernate.

Образец кода:

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

public static Session getCurrentSession(){
    Session session =  threadLocal.get();
    try {
        if(session ==null&&!session.isOpen()){
            //...
        }
        threadLocal.set(session);
    } catch (Exception e) {
        // TODO: handle exception
    }
    return session;
}

Посмотреть все вопросы интервью:«Наиболее 200 самых распространенных вопросов на собеседовании по Java»

использованная литература

woo woo Краткое описание.com/afraid/ah 1 Чэнду 61 волосы 2…

у-у-у. Краткое описание.com/afraid/98 не 68 из 97-х…

Отсканируйте QR-код ниже, чтобы следить за новостями:

公众号二维码

Рекомендуемые статьи по теме:

Более 200 самых распространенных вопросов на собеседовании по Java