Интерфейс ResourceScope
- Все суперинтерфейсы:
AutoCloseable
public sealed interface ResourceScope extends AutoCloseable
MemorySegment) связанные с областью ресурсов, могут быть доступны только пока область ресурсов активна (см. isAlive()), и только потоком, ассоциированным с областью ресурсов (если таковой имеется). Явные области ресурсов
Области ресурсов, полученные изnewConfinedScope(), newSharedScope() поддерживают детерминированное освобождение; мы называем эти области ресурсов явными областями. Явные области ресурсов могут быть закрыты явно (см. close()). Когда область ресурсов закрывается, она больше не активна (см. isAlive()), и последующие операции с ресурсами, связанными с этой областью (например, попытка доступа к экземпляру MemorySegment) завершатся ошибкой IllegalStateException. Закрытие области ресурсов вызовет все действия по очистке, связанные с этой областью (см. addCloseAction(Runnable)), и, возможно, освободит связанные с ней ресурсы (например):
- закрытие области, связанной с сегментом системной памяти, приводит к освобождению связанной с ним системной памяти (см.
MemorySegment.allocateNative(long, ResourceScope), илиSegmentAllocator.arenaAllocator(ResourceScope)) - закрытие области, связанной с отображённым сегментом памяти, приводит к отображению файла, с которым связан сегмент, (см.
MemorySegment.mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)) - закрытие области, связанной со «stub» вызова, приводит к освобождению «stub» (см.
CLinker.upcallStub(MethodHandle, FunctionDescriptor, ResourceScope)
Иногда явные области могут быть связаны с экземпляром Cleaner (см. newConfinedScope(Cleaner) и newSharedScope(Cleaner)). Такие области ресурсов называются управляемыми. Управляемая область ресурсов закрывается автоматически, когда экземпляр области становится недоступным.
Управляемые области могут быть полезны для прогнозируемого и детерминированного освобождения ресурсов, предотвращая при этом случайные утечки системной памяти. Если управляемая область ресурсов закрывается явно, дальнейших действий при потере доступности области не происходит. То есть, действия по очистке (см. addCloseAction(Runnable)), связанные с областью ресурсов (управляемой или нет), вызываются ровно один раз.
Неявные области ресурсов
Области ресурсов, полученные изnewImplicitScope(), не могут быть закрыты явно. Такие области ресурсов называются неявными. Вызов close() для неявной области ресурсов всегда приведёт к исключению. Ресурсы, связанные с неявными областями, освобождаются, когда область становится недоступной. Важной неявной областью является так называемая глобальная область; глобальная область — это неявная область, которая гарантированно никогда не станет недоступной. В результате глобальная область никогда не попытается освободить ресурсы, с ней связанные. Такие ресурсы должны, при необходимости, управляться клиентами независимо.
Привязка к потоку
Области ресурсов могут быть разделены на две категории: области ресурсов, привязанные к потоку, и общие области ресурсов. Области ресурсов, привязанные к потоку (см. newConfinedScope()), поддерживают жёсткую привязку к потоку. При создании им назначается владеющий поток, обычно поток, который инициировал операцию создания (см. ownerThread()). После создания привязанной к потоку области ресурсов, только владеющий поток сможет напрямую управлять ресурсами, связанными с этой областью. Любая попытка доступа к ресурсам из потока, отличного от владеющего, приведёт к сбою во время выполнения.
Общие области ресурсов (см. newSharedScope() и newImplicitScope()), с другой стороны, не имеют владеющего потока; ресурсы, связанные с такими общими областями, могут быть доступны нескольким потокам. Это может быть полезно, когда несколько потоков нуждаются в одновременном доступе к одному ресурсу (например, в случае параллельной обработки). Например, клиент может получить Spliterator из общего сегмента, который затем может быть использован для разделения сегмента и разрешения нескольким потокам работать параллельно над отдельными фрагментами сегмента. Следующий код может быть использован для суммирования всех целочисленных значений в сегменте памяти параллельно:
SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, MemoryLayouts.JAVA_INT); try (ResourceScope scope = ResourceScope.newSharedScope()) { MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope); VarHandle VH_int = SEQUENCE_LAYOUT.elementLayout().varHandle(int.class); int sum = StreamSupport.stream(segment.spliterator(SEQUENCE_LAYOUT), true) .mapToInt(s -> (int)VH_int.get(s.address())) .sum(); }
Явные общие области ресурсов, хотя и мощные, должны использоваться с осторожностью: если один или несколько потоков обращаются к ресурсу, связанному с общей областью, в то время как другая область закрывается другим потоком, может возникнуть ошибка в обоих потоках. Клиенты должны избегать многократного закрытия общей области ресурсов (например, многократного вызова close() до тех пор, пока не будет выброшено исключение). Вместо этого, клиенты общих областей ресурсов всегда должны обеспечивать правильные механизмы синхронизации (например, используя обработчики области ресурсов, см. ниже), чтобы потоки, закрывающие общие области ресурсов, никогда не конфликтовали с потоками, получающими доступ к ресурсам, управляемым теми же областями.
Обработчики областей ресурсов
Области ресурсов могут быть сделаны незакрываемыми путём получения одного или нескольких обработчиков области ресурсов (см.acquire()). Обработчик области ресурсов может быть использован, чтобы убедиться, что ресурсы, связанные с данной областью ресурсов (явной или неявной), не будут освобождены в течение определённого периода времени — например, во время критической области кода, затрагивающей один или несколько ресурсов, связанных с областью. Например, явная область ресурсов может быть закрыта только после закрытия всех обработчиков, полученных для данной области (см. close()). Это может быть полезно, когда клиентам нужно выполнить критическую операцию с сегментом памяти, в течение которой они должны убедиться, что сегмент не будет освобождён; это можно сделать следующим образом: Получение неявных областей ресурсов также возможно, но зачастую не требуется: так как ресурсы, связанные с неявной областью, будут освобождены только тогда, когда область станет недоступной, клиенты могут использовать, например,MemorySegment segment = ... ResourceScope.Handle segmentHandle = segment.scope().acquire() try { <critical operation on segment> } finally { segment.scope().release(segmentHandle); }
Reference.reachabilityFence(Object), чтобы убедиться, что ресурсы, связанные с неявными областями, не будут освобождены преждевременно. При этом приведённый выше фрагмент кода работает (тривиально) и для неявных областей.- Требования к реализации:
- Реализации этого интерфейса являются неизменяемыми, потокобезопасными и базовыми.
Краткое описание вложенных классов
| Модификатор и тип | Интерфейс | Описание |
|---|---|---|
static interface |
ResourceScope.Handle |
Абстракция, моделирующая дескриптор области ресурсов. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
ResourceScope.Handle |
acquire() |
Получает дескриптор области ресурсов, связанный с этой областью ресурсов. |
void |
addCloseAction |
Добавляет пользовательское действие очистки, которое будет выполнено при закрытии области ресурсов. |
void |
close() |
Закрывает эту область ресурсов. |
static ResourceScope |
globalScope() |
Возвращает неявную область, которая предполагается всегда активной. |
boolean |
isAlive() |
Активна ли эта область ресурсов? |
boolean |
isImplicit() |
Является ли эта область ресурсов неявной областью? |
static ResourceScope |
newConfinedScope() |
Создает новую ограниченную область. |
static ResourceScope |
newConfinedScope |
Создает новую ограниченную область, управляемую Cleaner. |
static ResourceScope |
newImplicitScope() |
Создает новую неявную область. |
static ResourceScope |
newSharedScope() |
Создает новую общую область. |
static ResourceScope |
newSharedScope |
Создает новую общую область, управляемую Cleaner. |
Thread |
ownerThread() |
Поток, владеющий этой областью ресурсов. |
void |
release |
Освобождает предоставленный дескриптор области ресурсов. |
Подробное описание методов
isAlive
boolean isAlive()
- Возвращает:
- true, если эта область ресурсов активна.
- См. также:
ownerThread
Thread ownerThread()
- Возвращает:
- владеющий этой областью ресурсов поток или
nullесли эта область ресурсов общая.
isImplicit
boolean isImplicit()
- Возвращает:
- true, если эта область является неявной областью.
- См. также:
close
void close()
IllegalStateException. Кроме того, при успешном закрытии все нативные ресурсы, связанные с этой областью ресурсов, будут освобождены.- Определено в:
-
closeв интерфейсеAutoCloseable - Примечание API:
- Эта операция не является идемпотентной; т.е., закрытие уже закрытой области ресурсов всегда приводит к возбуждению исключения. Это отражает сознательное конструкторское решение: переходы состояния области ресурсов должны быть явными в коде клиента; ошибка в любом из этих переходов показывает ошибку в логике приложения.
- Исключение:
-
IllegalStateException- если выполняется одно из следующих условий:- эта область ресурсов не активна
- эта область ресурсов ограниченная, и этот метод вызывается из потока, отличного от потока, владеющего этой областью ресурсов
- эта область ресурсов общая и к ресурсу, связанному с этой областью, обращаются во время вызова этого метода
- один или несколько дескрипторов (см.
acquire()) связанные с этой областью ресурсов, не были освобождены
-
UnsupportedOperationException- если эта область ресурсов неявная.
addCloseAction
void addCloseAction(Runnable runnable)
- Параметры:
-
runnable- пользовательское действие очистки, которое будет связано с этой областью. - Исключение:
-
IllegalStateException- если эта область уже закрыта.
acquire
ResourceScope.Handle acquire()
- Возвращает:
- дескриптор области ресурсов.
release
void release(ResourceScope.Handle handle)
- Параметры:
-
handle- дескриптор области ресурсов, который необходимо освободить. - Исключение:
-
IllegalArgumentException- если предоставленный дескриптор не связан с этой областью.
newConfinedScope
static ResourceScope newConfinedScope()
Cleaner.- Возвращает:
- новую ограниченную область.
newConfinedScope
static ResourceScope newConfinedScope(Cleaner cleaner)
Cleaner.- Параметры:
-
cleaner- очиститель, который должен быть связан с возвращаемой областью. - Возвращает:
- новую ограниченную область, управляемую
cleaner. - Исключение:
-
NullPointerException- еслиcleaner == null.
newImplicitScope
static ResourceScope newImplicitScope()
- Возвращает:
- новую неявную область.
globalScope
static ResourceScope globalScope()
- Возвращает:
- глобальную область.
© 1993, 2021, 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/17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/ResourceScope.html