本文主要研究一下Elasticsearch的Releasables

Releasable

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/lease/Releasable.java

public interface Releasable extends Closeable {    @Override    void close();}
  • Releasable继承了java.io.Closeable接口

Releasables

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/lease/Releasables.java

public enum Releasables {    ;    private static void close(Iterable<? extends Releasable> releasables, boolean ignoreException) {        try {            // this does the right thing with respect to add suppressed and not wrapping errors etc.            IOUtils.close(releasables);        } catch (IOException e) {            if (ignoreException == false) {                throw new UncheckedIOException(e);            }        }    }    /** Release the provided {@link Releasable}s. */    public static void close(Iterable<? extends Releasable> releasables) {        close(releasables, false);    }    /** Release the provided {@link Releasable}s. */    public static void close(Releasable... releasables) {        close(Arrays.asList(releasables));    }    /** Release the provided {@link Releasable}s, ignoring exceptions. */    public static void closeWhileHandlingException(Iterable<Releasable> releasables) {        close(releasables, true);    }    /** Release the provided {@link Releasable}s, ignoring exceptions. */    public static void closeWhileHandlingException(Releasable... releasables) {        closeWhileHandlingException(Arrays.asList(releasables));    }    /** Release the provided {@link Releasable}s, ignoring exceptions if <code>success</code> is {@code false}. */    public static void close(boolean success, Iterable<Releasable> releasables) {        if (success) {            close(releasables);        } else {            closeWhileHandlingException(releasables);        }    }    /** Release the provided {@link Releasable}s, ignoring exceptions if <code>success</code> is {@code false}. */    public static void close(boolean success, Releasable... releasables) {        close(success, Arrays.asList(releasables));    }    /** Wrap several releasables into a single one. This is typically useful for use with try-with-resources: for example let's assume     *  that you store in a list several resources that you would like to see released after execution of the try block:     *     *  <pre>     *  List&lt;Releasable&gt; resources = ...;     *  try (Releasable releasable = Releasables.wrap(resources)) {     *      // do something     *  }     *  // the resources will be released when reaching here     *  </pre>     */    public static Releasable wrap(final Iterable<Releasable> releasables) {        return () -> close(releasables);    }    /** @see #wrap(Iterable) */    public static Releasable wrap(final Releasable... releasables) {        return () -> close(releasables);    }    /**     * Equivalent to {@link #wrap(Releasable...)} but can be called multiple times without double releasing.     */    public static Releasable releaseOnce(final Releasable... releasables) {        final AtomicBoolean released = new AtomicBoolean(false);        return () -> {            if (released.compareAndSet(false, true)) {                close(releasables);            }        };    }}
  • Releasables提供close、closeWhileHandlingException、wrap、releaseOnce静态方法用于更方便地使用Releasable

实例

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/index/translog/Translog.java

public class Translog extends AbstractIndexShardComponent implements IndexShardComponent, Closeable {    //......    public static void writeOperations(StreamOutput outStream, List<Operation> toWrite) throws IOException {        final ReleasableBytesStreamOutput out = new ReleasableBytesStreamOutput(BigArrays.NON_RECYCLING_INSTANCE);        try {            outStream.writeInt(toWrite.size());            final BufferedChecksumStreamOutput checksumStreamOutput = new BufferedChecksumStreamOutput(out);            for (Operation op : toWrite) {                out.reset();                final long start = out.position();                out.skip(Integer.BYTES);                writeOperationNoSize(checksumStreamOutput, op);                long end = out.position();                int operationSize = (int) (out.position() - Integer.BYTES - start);                out.seek(start);                out.writeInt(operationSize);                out.seek(end);                ReleasablePagedBytesReference bytes = out.bytes();                bytes.writeTo(outStream);            }        } finally {            Releasables.close(out);        }    }    //......}
  • writeOperations在finally中使用Releasables.close关闭了ReleasableBytesStreamOutput

小结

Releasables提供close、closeWhileHandlingException、wrap、releaseOnce静态方法用于更方便地使用Releasable

doc

  • Releasables