< prev index next >

src/java.base/share/classes/java/io/FileInputStream.java

Print this page
rev 15897 : 8168640: (fc) Avoiding AtomicBoolean in FileInput/-OutputStream improves startup
Reviewed-by: alanb, shade, plevart

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -24,11 +24,10 @@
  */
 
 package java.io;
 
 import java.nio.channels.FileChannel;
-import java.util.concurrent.atomic.AtomicBoolean;
 import sun.nio.ch.FileChannelImpl;
 
 
 /**
  * A <code>FileInputStream</code> obtains input bytes

@@ -58,11 +57,13 @@
      */
     private final String path;
 
     private volatile FileChannel channel;
 
-    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final Object closeLock = new Object();
+
+    private volatile boolean closed;
 
     /**
      * Creates a <code>FileInputStream</code> by
      * opening a connection to an actual file,
      * the file named by the path name <code>name</code>

@@ -311,17 +312,24 @@
      *
      * @revised 1.4
      * @spec JSR-51
      */
     public void close() throws IOException {
-        if (!closed.compareAndSet(false, true)) {
-            // if compareAndSet() returns false closed was already true
+        if (closed) {
+            return;
+        }
+        synchronized (closeLock) {
+            if (closed) {
             return;
         }
+            closed = true;
+        }
 
         FileChannel fc = channel;
         if (fc != null) {
+            // possible race with getChannel(), benign since
+            // FileChannel.close is final and idempotent
            fc.close();
         }
 
         fd.closeAll(new Closeable() {
             public void close() throws IOException {

@@ -368,12 +376,14 @@
         if (fc == null) {
             synchronized (this) {
                 fc = this.channel;
                 if (fc == null) {
                     this.channel = fc = FileChannelImpl.open(fd, path, true, false, this);
-                    if (closed.get()) {
+                    if (closed) {
                         try {
+                            // possible race with close(), benign since
+                            // FileChannel.close is final and idempotent
                             fc.close();
                         } catch (IOException ioe) {
                             throw new InternalError(ioe); // should not happen
                         }
                     }
< prev index next >