src/java.base/share/classes/java/util/zip/Deflater.java
changeset 48238 9f225d4387e2
parent 47216 71c04702a3d5
child 48337 0ee20aad71c4
--- a/src/java.base/share/classes/java/util/zip/Deflater.java	Mon Dec 11 18:33:53 2017 +0100
+++ b/src/java.base/share/classes/java/util/zip/Deflater.java	Mon Dec 11 11:45:02 2017 -0800
@@ -67,12 +67,26 @@
  * }
  * </pre></blockquote>
  *
+ * @apiNote
+ * To release resources used by this {@code Deflater}, the {@link #end()} method
+ * should be called explicitly. Subclasses are responsible for the cleanup of resources
+ * acquired by the subclass. Subclasses that override {@link #finalize()} in order
+ * to perform cleanup should be modified to use alternative cleanup mechanisms such
+ * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
+ *
+ * @implSpec
+ * If this {@code Deflater} has been subclassed and the {@code end} method has been
+ * overridden, the {@code end} method will be called by the finalization when the
+ * deflater is unreachable. But the subclasses should not depend on this specific
+ * implementation; the finalization is not reliable and the {@code finalize} method
+ * is deprecated to be removed.
+ *
  * @see         Inflater
  * @author      David Connelly
  * @since 1.1
  */
-public
-class Deflater {
+
+public class Deflater {
 
     private final ZStreamRef zsRef;
     private byte[] buf = new byte[0];
@@ -169,7 +183,9 @@
     public Deflater(int level, boolean nowrap) {
         this.level = level;
         this.strategy = DEFAULT_STRATEGY;
-        this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
+        this.zsRef = ZStreamRef.get(this,
+                () -> init(level, DEFAULT_STRATEGY, nowrap),
+                Deflater::end);
     }
 
     /**
@@ -534,38 +550,32 @@
 
     /**
      * Closes the compressor and discards any unprocessed input.
+     *
      * This method should be called when the compressor is no longer
-     * being used, but will also be called automatically by the
-     * finalize() method. Once this method is called, the behavior
-     * of the Deflater object is undefined.
+     * being used. Once this method is called, the behavior of the
+     * Deflater object is undefined.
      */
     public void end() {
         synchronized (zsRef) {
-            long addr = zsRef.address();
-            zsRef.clear();
-            if (addr != 0) {
-                end(addr);
-                buf = null;
-            }
+            zsRef.clean();
+            buf = null;
         }
     }
 
     /**
      * Closes the compressor when garbage is collected.
      *
-     * @deprecated The {@code finalize} method has been deprecated.
-     *     Subclasses that override {@code finalize} in order to perform cleanup
-     *     should be modified to use alternative cleanup mechanisms and
-     *     to remove the overriding {@code finalize} method.
-     *     When overriding the {@code finalize} method, its implementation must explicitly
-     *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
-     *     See the specification for {@link Object#finalize()} for further
-     *     information about migration options.
+     * @deprecated The {@code finalize} method has been deprecated and will be
+     *     removed. It is implemented as a no-op. Subclasses that override
+     *     {@code finalize} in order to perform cleanup should be modified to use
+     *     alternative cleanup mechanisms and to remove the overriding {@code finalize}
+     *     method. The recommended cleanup for compressor is to explicitly call
+     *     {@code end} method when it is no longer in use. If the {@code end} is
+     *     not invoked explicitly the resource of the compressor will be released
+     *     when the instance becomes unreachable.
      */
-    @Deprecated(since="9")
-    protected void finalize() {
-        end();
-    }
+    @Deprecated(since="9", forRemoval=true)
+    protected void finalize() {}
 
     private void ensureOpen() {
         assert Thread.holdsLock(zsRef);