Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels) Summary: [Nested Classes](https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#nestedclasses) \| [Ctors](https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#pubctors) \| [Methods](https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#pubmethods) \| [Protected Methods](https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#promethods) \| [Inherited Methods](https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#inhmethods)

# MultiResolutionImageReader

*** ** * ** ***


`
public


class
MultiResolutionImageReader
`


`

extends https://developer.android.com/reference/java/lang/Object


`

`


implements

https://developer.android.com/reference/java/lang/AutoCloseable


`

|---|---|
| [java.lang.Object](https://developer.android.com/reference/java/lang/Object) ||
| ↳ | android.hardware.camera2.MultiResolutionImageReader |

<br />

*** ** * ** ***

<br />

The MultiResolutionImageReader class wraps a group of `https://developer.android.com/reference/android/media/ImageReader` with
the same format and different sizes, source camera Id, or camera sensor modes.

The main use case of this class is for a
`https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA` or an ultra high resolution sensor camera to output variable-size images. For a
logical multi-camera which implements optical zoom, different physical cameras may have different
maximum resolutions. As a result, when the camera device switches between physical cameras
depending on zoom ratio, the maximum resolution for a particular format may change. For an
ultra high resolution sensor camera, the camera device may deem it better or worse to run in
maximum resolution mode / default mode depending on lighting conditions. So the application may
choose to let the camera device decide on its behalf.

MultiResolutionImageReader should be used for a camera device only if the camera device
supports multi-resolution output stream by advertising the specified output format in `https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP`.

To acquire images from the MultiResolutionImageReader, the application must use the
`https://developer.android.com/reference/android/media/ImageReader` object passed by
`https://developer.android.com/reference/android/media/ImageReader.OnImageAvailableListener#onImageAvailable(android.media.ImageReader)` callback to call
`https://developer.android.com/reference/android/media/ImageReader#acquireNextImage()` or `https://developer.android.com/reference/android/media/ImageReader#acquireLatestImage()`. The application
must not use the `https://developer.android.com/reference/android/media/ImageReader` passed by an `https://developer.android.com/reference/android/media/ImageReader.OnImageAvailableListener#onImageAvailable(android.media.ImageReader)` callback to acquire future images
because future images may originate from a different `https://developer.android.com/reference/android/media/ImageReader` contained within the
`MultiResolutionImageReader`.

Note that by default, for a MultiResolutionImageReader, each capture request produces only
one output buffer from one internal reader. Some devices also support producing from multiple
readers for a single CaptureRequest (for example, by running multiple sensors at the same time).
Support for this can be queried by `https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamConfigurationMap#isConcurrentReadersSupported(int)` and enabled by using `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.Builder#setConcurrentOutputsEnabled(boolean)`.

<br />

**See also:**

- `https://developer.android.com/reference/android/media/ImageReader`
- `https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP`

## Summary

| ### Nested classes ||
|---|---|
| ` class` | `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.Builder` Builder class for `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader` objects. |
| ` interface` | `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener` Callback interface for being notified of the surfaces used for the capture. |

| ### Public constructors ||
|---|---|
| ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#MultiResolutionImageReader(java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>,%20int,%20int)(https://developer.android.com/reference/java/util/Collection<https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamInfo> streams, int format, int maxImages) ` Create a new multi-resolution reader based on a group of camera stream properties returned by a camera device. |
| ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#MultiResolutionImageReader(java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>,%20int,%20int,%20long)(https://developer.android.com/reference/java/util/Collection<https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamInfo> streams, int format, int maxImages, long usage) ` Create a new multi-resolution reader based on a group of camera stream properties returned by a camera device, and the desired format, maximum buffer capacity and consumer usage flag. |

| ### Public methods ||
|---|---|
| ` void` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#close()() ` Closes this resource, relinquishing any underlying resources. |
| ` void` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#flush()() ` Flush pending images from all internal ImageReaders Acquire and close pending images from all internal ImageReaders. |
| ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#getOnActiveOutputSurfacesListener()() ` Get the `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener` currently registered for this MultiResolutionImageReader. |
| ` https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamInfo` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#getStreamInfoForImageReader(android.media.ImageReader)(https://developer.android.com/reference/android/media/ImageReader reader) ` Get the MultiResolutionStreamInfo describing the ImageReader an image originates from An image from a `MultiResolutionImageReader` is produced from one of the underlying `ImageReader`s. |
| ` https://developer.android.com/reference/android/view/Surface` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#getSurface()() ` Get the surface that is used as a target for `https://developer.android.com/reference/android/hardware/camera2/CaptureRequest` The application must use the surface returned by this function as a target for `https://developer.android.com/reference/android/hardware/camera2/CaptureRequest`. |
| ` void` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#setOnActiveOutputSurfacesListener(java.util.concurrent.Executor,%20android.hardware.camera2.MultiResolutionImageReader.OnActiveOutputSurfacesListener)(https://developer.android.com/reference/java/util/concurrent/Executor executor, https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener listener) ` Register a listener to be notified of active output surfaces for a concurrency-enabled MultiResolutionImageReader. |
| ` void` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener,%20java.util.concurrent.Executor)(https://developer.android.com/reference/android/media/ImageReader.OnImageAvailableListener listener, https://developer.android.com/reference/java/util/concurrent/Executor executor) ` Set onImageAvailableListener callback. |

| ### Protected methods ||
|---|---|
| ` void` | ` https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#finalize()() ` Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. |

| ### Inherited methods |
|---|---|
| From class ` https://developer.android.com/reference/java/lang/Object ` |---|---| | ` https://developer.android.com/reference/java/lang/Object` | ` https://developer.android.com/reference/java/lang/Object#clone()() ` Creates and returns a copy of this object. | | ` boolean` | ` https://developer.android.com/reference/java/lang/Object#equals(java.lang.Object)(https://developer.android.com/reference/java/lang/Object obj) ` Indicates whether some other object is "equal to" this one. | | ` void` | ` https://developer.android.com/reference/java/lang/Object#finalize()() ` Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. | | ` final https://developer.android.com/reference/java/lang/Class<?>` | ` https://developer.android.com/reference/java/lang/Object#getClass()() ` Returns the runtime class of this `Object`. | | ` int` | ` https://developer.android.com/reference/java/lang/Object#hashCode()() ` Returns a hash code value for the object. | | ` final void` | ` https://developer.android.com/reference/java/lang/Object#notify()() ` Wakes up a single thread that is waiting on this object's monitor. | | ` final void` | ` https://developer.android.com/reference/java/lang/Object#notifyAll()() ` Wakes up all threads that are waiting on this object's monitor. | | ` https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/lang/Object#toString()() ` Returns a string representation of the object. | | ` final void` | ` https://developer.android.com/reference/java/lang/Object#wait(long,%20int)(long timeoutMillis, int nanos) ` Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed. | | ` final void` | ` https://developer.android.com/reference/java/lang/Object#wait(long)(long timeoutMillis) ` Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed. | | ` final void` | ` https://developer.android.com/reference/java/lang/Object#wait()() ` Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*. | ||
| From interface ` https://developer.android.com/reference/java/lang/AutoCloseable ` |---|---| | ` abstract void` | ` https://developer.android.com/reference/java/lang/AutoCloseable#close()() ` Closes this resource, relinquishing any underlying resources. | ||

## Public constructors

### MultiResolutionImageReader

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public MultiResolutionImageReader (Collection<MultiResolutionStreamInfo> streams, 
                int format, 
                int maxImages)
```

Create a new multi-resolution reader based on a group of camera stream properties returned
by a camera device.

This constructor is the equivalent of
`https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#MultiResolutionImageReader(java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>,%20int,%20int,%20long)`
without specifying `usage`.

See `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#MultiResolutionImageReader(java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>,%20int,%20int,%20long)`
for full details.

<br />

<br />

| Parameters ||
|---|---|
| `streams` | `Collection`: The group of multi-resolution stream info. This value cannot be `null`. <br /> |
| `format` | `int`: The format of the Image that this multi-resolution reader will produce. <br /> |
| `maxImages` | `int`: The maximum number of images the user will want to access simultaneously. Value is 1 or greater <br /> |

### MultiResolutionImageReader

Added in [API level 36](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public MultiResolutionImageReader (Collection<MultiResolutionStreamInfo> streams, 
                int format, 
                int maxImages, 
                long usage)
```

Create a new multi-resolution reader based on a group of camera stream properties returned
by a camera device, and the desired format, maximum buffer capacity and consumer usage flag.


The valid size and formats depend on the camera characteristics.
`MultiResolutionImageReader` for an image format is supported by the camera device if
the format is in the supported multi-resolution output stream formats returned by
`https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamConfigurationMap#getOutputFormats()`.
If the image format is supported, the `MultiResolutionImageReader` object can be
created with the `streams` objects returned by
`https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamConfigurationMap#getOutputInfo(int)`.


The `maxImages` parameter determines the maximum number of
`https://developer.android.com/reference/android/media/Image` objects that can be acquired from each of the `ImageReader`
within the `MultiResolutionImageReader`. However, requesting more buffers will
use up more memory, so it is important to use only the minimum number necessary. The
application is strongly recommended to acquire no more than `maxImages` images
from all of the internal ImageReader objects combined. By keeping track of the number of
acquired images for the MultiResolutionImageReader, the application doesn't need to do the
bookkeeping for each internal ImageReader returned from `https://developer.android.com/reference/android/media/ImageReader.OnImageAvailableListener#onImageAvailable(android.media.ImageReader)` callback.


Unlike the normal ImageReader, the MultiResolutionImageReader has a more complex
configuration sequence. Instead of passing the same surface to OutputConfiguration and
CaptureRequest, the
`https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration#createInstancesForMultiResolutionOutput(android.hardware.camera2.MultiResolutionImageReader)`
call needs to be used to create the OutputConfigurations for session creation, and then
`https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader#getSurface()` is used to get `https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.Builder#addTarget(android.view.Surface)`.

<br />

<br />

| Parameters ||
|---|---|
| `streams` | `Collection`: The group of multi-resolution stream info, which is used to create a multi-resolution reader containing a number of ImageReader objects. Each ImageReader object represents a multi-resolution stream in the group. This value cannot be `null`. <br /> |
| `format` | `int`: The format of the Image that this multi-resolution reader will produce. This must be one of the `https://developer.android.com/reference/android/graphics/ImageFormat` or `https://developer.android.com/reference/android/graphics/PixelFormat` constants. Note that not all formats are supported, like ImageFormat.NV21. The supported multi-resolution reader format can be queried by `https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamConfigurationMap#getOutputFormats()`. <br /> |
| `maxImages` | `int`: The maximum number of images the user will want to access simultaneously. This should be as small as possible to limit memory use. Once maxImages images are obtained by the user from any given internal ImageReader, one of them has to be released before a new Image will become available for access through the ImageReader's `https://developer.android.com/reference/android/media/ImageReader#acquireLatestImage()` or `https://developer.android.com/reference/android/media/ImageReader#acquireNextImage()`. Must be greater than 0. Value is 1 or greater <br /> |
| `usage` | `long`: The intended usage of the images produced by the internal ImageReader. See the usages on `https://developer.android.com/reference/android/hardware/HardwareBuffer` for a list of valid usage bits. See also `https://developer.android.com/reference/android/hardware/HardwareBuffer#isSupported(int,%20int,%20int,%20int,%20long)` for checking if a combination is supported. If it's not supported this will throw an `https://developer.android.com/reference/java/lang/IllegalArgumentException`. Value is either `0` or a combination of the following: - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_CPU_READ_RARELY` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_CPU_READ_OFTEN` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_CPU_WRITE_RARELY` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_CPU_WRITE_OFTEN` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_GPU_COLOR_OUTPUT` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_COMPOSER_OVERLAY` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_PROTECTED_CONTENT` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_VIDEO_ENCODE` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_GPU_DATA_BUFFER` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_SENSOR_DIRECT_DATA` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_GPU_CUBE_MAP` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_GPU_MIPMAP_COMPLETE` - `https://developer.android.com/reference/android/hardware/HardwareBuffer#USAGE_FRONT_BUFFER` |

**See also:**

- `https://developer.android.com/reference/android/media/Image`
- `https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP`
- `https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamConfigurationMap`

## Public methods

### close

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void close ()
```

Closes this resource, relinquishing any underlying resources.
This method is invoked automatically on objects managed by the
`try`-with-resources statement.

<br />

### flush

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void flush ()
```

Flush pending images from all internal ImageReaders

Acquire and close pending images from all internal ImageReaders. This has the same
effect as calling acquireLatestImage() on all internal ImageReaders, and closing all
latest images.

<br />

<br />

### getOnActiveOutputSurfacesListener

Added in [API level 37](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public MultiResolutionImageReader.OnActiveOutputSurfacesListener getOnActiveOutputSurfacesListener ()
```

Get the `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener` currently registered for this
MultiResolutionImageReader.

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener` | The listener, or `null` if no listener is currently registered. <br /> |

### getStreamInfoForImageReader

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public MultiResolutionStreamInfo getStreamInfoForImageReader (ImageReader reader)
```

Get the MultiResolutionStreamInfo describing the ImageReader an image originates from

An image from a `MultiResolutionImageReader` is produced from one of the underlying
`ImageReader`s. This function returns the `https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamInfo` to describe
the property for that `ImageReader`, such as width, height, and physical camera Id.

<br />

<br />

| Parameters ||
|---|---|
| `reader` | `ImageReader`: An internal ImageReader within `MultiResolutionImageReader`. This value cannot be `null`. <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/android/hardware/camera2/params/MultiResolutionStreamInfo` | The stream info describing the internal `ImageReader`. This value cannot be `null`. <br /> |

### getSurface

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public Surface getSurface ()
```

Get the surface that is used as a target for `https://developer.android.com/reference/android/hardware/camera2/CaptureRequest`

The application must use the surface returned by this function as a target for
`https://developer.android.com/reference/android/hardware/camera2/CaptureRequest`. The camera device makes the decision on which internal
`ImageReader` will receive the output image.

Please note that holding on to the Surface objects returned by this method is not enough
to keep their parent MultiResolutionImageReaders from being reclaimed. In that sense, a
Surface acts like a `https://developer.android.com/reference/java/lang/ref/WeakReference` to the
MultiResolutionImageReader that provides it.

<br />

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/android/view/Surface` | a `https://developer.android.com/reference/android/view/Surface` to use as the target for a capture request. This value cannot be `null`. <br /> |

### setOnActiveOutputSurfacesListener

Added in [API level 37](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void setOnActiveOutputSurfacesListener (Executor executor, 
                MultiResolutionImageReader.OnActiveOutputSurfacesListener listener)
```

Register a listener to be notified of active output surfaces for a
concurrency-enabled MultiResolutionImageReader.

See `https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.OnActiveOutputSurfacesListener#onActiveOutputSurfaces(java.util.List<android.view.Surface>,%20long,%20long)` for more details.

<br />

<br />

| Parameters ||
|---|---|
| `executor` | `Executor`: The executor which will be used to invoke the callback. This value cannot be `null`. Callback and listener events are dispatched through this `https://developer.android.com/reference/java/util/concurrent/Executor`, providing an easy way to control which thread is used. To dispatch events through the main thread of your application, you can use `https://developer.android.com/reference/android/content/Context#getMainExecutor()`. Otherwise, provide an `https://developer.android.com/reference/java/util/concurrent/Executor` that dispatches to an appropriate thread. <br /> |
| `listener` | `MultiResolutionImageReader.OnActiveOutputSurfacesListener`: The listener that will be run. This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | If the executor or listener is null. |
| `https://developer.android.com/reference/java/lang/IllegalStateException` | If the MultiResolutionImageReader is created without enabling concurrency. |

### setOnImageAvailableListener

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void setOnImageAvailableListener (ImageReader.OnImageAvailableListener listener, 
                Executor executor)
```

Set onImageAvailableListener callback.

This function sets the onImageAvailableListener for all the internal
`https://developer.android.com/reference/android/media/ImageReader` objects.

For a multi-resolution ImageReader, the timestamps of images acquired in
onImageAvailable callback from different internal ImageReaders may become
out-of-order due to the asynchronous callbacks between the different resolution
image queues.

<br />

<br />

| Parameters ||
|---|---|
| `listener` | `ImageReader.OnImageAvailableListener`: The listener that will be run. This value may be `null`. <br /> |
| `executor` | `Executor`: The executor which will be used when invoking the callback. This value may be `null`. Callback and listener events are dispatched through this `https://developer.android.com/reference/java/util/concurrent/Executor`, providing an easy way to control which thread is used. To dispatch events through the main thread of your application, you can use `https://developer.android.com/reference/android/content/Context#getMainExecutor()`. Otherwise, provide an `https://developer.android.com/reference/java/util/concurrent/Executor` that dispatches to an appropriate thread. <br /> |

## Protected methods

### finalize

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
protected void finalize ()
```

Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.
A subclass overrides the `finalize` method to dispose of
system resources or to perform other cleanup.


The general contract of `finalize` is that it is invoked
if and when the Java virtual
machine has determined that there is no longer any
means by which this object can be accessed by any thread that has
not yet died, except as a result of an action taken by the
finalization of some other object or class which is ready to be
finalized. The `finalize` method may take any action, including
making this object available again to other threads; the usual purpose
of `finalize`, however, is to perform cleanup actions before
the object is irrevocably discarded. For example, the finalize method
for an object that represents an input/output connection might perform
explicit I/O transactions to break the connection before the object is
permanently discarded.


The `finalize` method of class `Object` performs no
special action; it simply returns normally. Subclasses of
`Object` may override this definition.


The Java programming language does not guarantee which thread will
invoke the `finalize` method for any given object. It is
guaranteed, however, that the thread that invokes finalize will not
be holding any user-visible synchronization locks when finalize is
invoked. If an uncaught exception is thrown by the finalize method,
the exception is ignored and finalization of that object terminates.


After the `finalize` method has been invoked for an object, no
further action is taken until the Java virtual machine has again
determined that there is no longer any means by which this object can
be accessed by any thread that has not yet died, including possible
actions by other objects or classes which are ready to be finalized,
at which point the object may be discarded.


The `finalize` method is never invoked more than once by a Java
virtual machine for any given object.


Any exception thrown by the `finalize` method causes
the finalization of this object to be halted, but is otherwise
ignored.

<br />