Класс ClassValue<T>
- Параметры типа:
-
T- тип производного значения
public abstract class ClassValue<T> extends Object
ClassValue для кэширования информации, необходимой для быстрого отправки сообщения, для каждого встреченного класса.- С:
- 1.7
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
protected |
Единственный конструктор. |
Краткое описание методов
Подробное описание конструкторов
ClassValue
protected ClassValue()
Подробное описание методов
computeValue
protected abstract T computeValue(Class<?> type)
ClassValue. Этот метод будет вызван в первом потоке, который обращается к значению с методом get.
Обычно этот метод вызывается не более одного раза на класс, но он может быть вызван снова, если был сделан вызов remove.
Если этот метод вызывает исключение, соответствующий вызов get завершится с этим исключением, и значение класса не будет записано.
- Параметры:
-
type- тип, значение класса которого необходимо вычислить - Возвращает:
- нововычисленное значение, связанное с этим
ClassValue, для данного класса или интерфейса - См. также:
get
public T get(Class<?> type)
computeValue. Фактическая установка значения на класс выполняется атомарно. В этот момент, если несколько конкурирующих потоков вычислили значения, выбирается одно и возвращается всем конкурирующим потокам.
Параметр type обычно является классом, но это может быть любой тип, такой как интерфейс, примитивный тип (например, int.class) или void.class.
В отсутствие вызовов remove, значение класса имеет простую диаграмму состояний: неинициализированное и инициализированное. При выполнении вызовов remove, правила наблюдения за значением сложнее. См. документацию для remove для получения дополнительной информации.
- Параметры:
-
type- тип, значение класса которого необходимо вычислить или получить - Возвращает:
- текущее значение, связанное с этим
ClassValue, для данного класса или интерфейса - Исключение:
-
NullPointerException- если аргумент равен null - См. также:
remove
public void remove(Class<?> type)
computeValue. Это может привести к дополнительному вызову метода computeValue для данного класса. Для объяснения взаимодействия между вызовами get и remove, мы должны смоделировать переходы состояния значения класса, учитывая чередование между неинициализированными и инициализированными состояниями. Для этого пронумеруем эти состояния последовательно, обращая внимание на то, что неинициализированные (или удаленные) состояния имеют четные номера, а инициализированные (или повторно инициализированные) состояния имеют нечетные номера.
Когда поток T удаляет значение класса в состоянии 2N, ничего не происходит, так как значение класса уже неинициализировано. В противном случае состояние атомарно переходит в состояние 2N+1.
Когда поток T запрашивает значение класса в состоянии 2N, поток сначала пытается инициализировать значение класса в состояние 2N+1 вызовом computeValue и установкой полученного значения.
Когда T пытается установить нововычисленное значение, если состояние все еще в 2N, значение класса будет инициализировано вычисленным значением, переходя в состояние 2N+1.
В противном случае, независимо от того, четное или нечетное новое состояние, T отбросит нововычисленное значение и повторит операцию get.
Отбрасывание и повторная попытка являются важным условием, так как в противном случае T может потенциально установить катастрофически устаревшее значение. Например:
-
TвызываетCV.get(C)и видит состояние2N -
Tбыстро вычисляет зависящее от времени значениеV0и готовится к его установке -
Tсталкивается с неудачным событием страничной подгрузки или планирования и засыпает на долгое время - ...в то же время
T2также вызываетCV.get(C)и видит состояние2N -
T2быстро вычисляет аналогичное зависящее от времени значениеV1и устанавливает его наCV.get(C) -
T2(или третий поток) затем вызываетCV.remove(C), отменяя работуT2 - предыдущие действия
T2повторяются несколько раз - также, соответствующие вычисленные значения меняются со временем:
V1,V2, ... - ...в то же время
Tпросыпается и пытается установитьV0; это должно завершиться неудачей
CV.computeValue использует блокировки для правильного наблюдения за зависящими от времени состояниями при вычислении V1, и т. д. Это не устраняет угрозу устаревшего значения, так как существует временной интервал между возвратом computeValue в T и установкой нового значения. Во время этого процесса невозможно никакой пользовательской синхронизации.- Параметры:
-
type- тип, значение класса которого необходимо удалить - Исключение:
-
NullPointerException- если аргумент равен null
© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ClassValue.html