Главная » Java » Переменные ThreadLocal Java

2

Класс ThreadLocal предоставляет возможность иметь единую логическую переменную, обладающую независимыми значениями в контексте каждого отдельного потока. В составе объекта ThreadLocal есть методы set и get, которые позволяют соответственно присваивать и считывать значения переменной для текущего потока. Хотя это средство, возможно, вам никогда не понадобится, при случае оно способно существенно упростить работу.

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

public class Operations {

static class User {

static final User UNKNOWN_USER = new User();

} ;

boolean canChange(user u) { return true; }

private static ThreadLocal users = new ThreadLocal() {

/** в качестве исходного используется значение UNKNOWN_USER */

protected Object initialvalue() {

return User.UNKNOWN_USER;

}

} ;

private static User currentuser() {

return (user) users.get();

}

public static void setuser(user’newuser) {

users.set(newuser);

}

public void setValue(int newValue) {

user user т currentUser();

if (!canchange(user))

throw new securityException();

// … изменить значение .. ,

}

// …

}

Статическое поле users содержит переменную типа ThreadLocal, в качестве исходного значения которой в каждом потоке употребляется User. UNKNOWN_USER. Это значение воспроизводится с помощью переопределенной версии метода initiаlValue, который по умолчанию возвращает null. Пользовательский объект ставится в соответствие текущему потоку посредством вызова метода setUser. Информация о ранее определенном пользовательском объекте текущего потока может быть получена с помощью метода currentUser. Как видно из текста метода setValue, данные пользовательского объекта далее находят применение для определения привилегий потока.

Когда поток прекращает существование, значения, установленные для этого потока в переменных Thread Local, недостижимы и могут быть уничтожены сборщиком мусора, если какие-либо ссылки на них отсутствуют.

При создании нового потока в качестве соответствующего исходного значения переменной ThreadLocal используется то, которое возвращается методом initiаlValue. Если необходимо, чтобы новый поток наследовал исходное значение, отвечающее потоку-"родителю", можно обратиться к средствам класса InheгitableThreadLocal, производного от ThreadLocal. Он содержит метод childValue, вызываемый для получения исходного значения переменной для дочернего потока. Методу передается значение переменной, соответствующее потоку-"родителю", а возвращает он значение для дочернего потока. По умолчанию childValue возвращает то же значение, которое получает в виде параметра, но ничто не мешает создать производный класс и переопределить метод, чтобы тот формировал нужный клонированный вариант исходного значения переменной, отвечающего дочернему потоку.

Использование переменных ThreadLocal связано с определенным риском.

Обращаться к ним следует только в том случае, если вы отчетливо представляете особенности применяемой модели многопоточных вычислений. Проблемы возникают, в частности, при обращении к модели пула потоков (thread pool), когда для решения очередной задачи вместо создания нового потока предусматривается повторное использование одного из ранее сформированных потоков. В системе, поддерживающей пул потоков, каждый поток может применяться несколько раз. В этом случае любая переменная ThreadLocal к моменту начала очередного сеанса работы потока вместо требуемого исходного значения, обычно возвращаемого методами initiаlValue или childValue, будет содержать значение, оставшееся после завершения предыдущего сеанса. Если вы создали класс общего назначения, предусматривающий использование переменных ThreadLocal, а кто-то позже решит применить его в системе с пулом потоков, последствия могут быть совершенно неожиданными. Подобная ситуация, например, вполне применима к переменной users из рассмотренного выше класса Ореrations  если объект Ореrations используется несколькими потоками или несколько объектов Ореrations находят применение в контексте одного и того же Потока, понятие "текущий пользовательский объект" легко исказить. Программисты, обращающиеся к классу Operations, должны ясно это понимать и Использовать объекты Ореrations только в таких многопоточных средах, которым отвечает контракт класса.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии

Комментариев 2

  1. ISPDN says:

    Согласно изменениям, внесённым законом № 363-ФЗ от 27 декабря 2009 года, операторы персональных данных должны привести свои системы обработки персональных данных, запущенные до 1 января 2010 года, в соответствие с законом до 1 июля 2011 года. Федеральным законом от 23 декабря 2010 года № 359-ФЗ «О внесении изменения в статью 25 федерального закона „О персональных данных“» срок приведения информационных систем персональных данных, созданных до 1 января 2011 года, в соответствие с требованиями закона № 152-ФЗ – не позднее 1 июля 2011 года. Последние изменения были внесены федеральным законом № 261-ФЗ от 25.07.2011. Этим законом была уточнена сфера действия Федерального закона «О персональных данных», используемые в нём основные понятия, принципы и условия обработки персональных данных. Существенно переработаны действующие законодательные нормы, касающиеся трансграничной передачи персональных данных, мер по обеспечению безопасности персональных данных при их обработке, прав и обязанностей оператора, взаимоотношений оператора и субъекта персональных данных.До 1 июля 2011 года все операторы (тоесть все, кто использует в работе автоматизированные системы, т.е. компьютеры) Оператор обязан принимать меры, необходимые и достаточные для обеспечения выполнения обязанностей, предусмотренных настоящим Федеральным законом и принятыми в соответствии с ним нормативными правовыми актами. Оператор самостоятельно определяет состав и перечень мер, необходимых и достаточных для обеспечения выполнения обязанностей, предусмотренных настоящим Федеральным законом и принятыми в соответствии с ним нормативными правовыми актами, если иное не предусмотрено настоящим Федеральным законом или другими федеральными законами. Вопрос ко всем, кто уже готов к соответствию 152-ФЗ? Какие меры приняты? Какие сертифицированные средства защиты информации используются у Вас на предприятии??