src/java.base/share/classes/java/net/Socket.java
branchniosocketimpl-branch
changeset 57188 1f2101ee432d
parent 57187 056911ad3ee7
child 57190 4964feb6d75d
--- a/src/java.base/share/classes/java/net/Socket.java	Sat Feb 16 19:53:43 2019 +0000
+++ b/src/java.base/share/classes/java/net/Socket.java	Sun Feb 17 10:00:26 2019 +0000
@@ -28,6 +28,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import java.nio.channels.SocketChannel;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -75,6 +77,22 @@
     private boolean oldImpl = false;
 
     /**
+     * Socket input/output streams
+     */
+    private volatile InputStream in;
+    private volatile OutputStream out;
+    private static final VarHandle IN, OUT;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            IN = l.findVarHandle(Socket.class, "in", InputStream.class);
+            OUT = l.findVarHandle(Socket.class, "out", OutputStream.class);
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
+
+    /**
      * Creates an unconnected socket, with the
      * system-default type of SocketImpl.
      *
@@ -920,8 +938,15 @@
             throw new SocketException("Socket is not connected");
         if (isInputShutdown())
             throw new SocketException("Socket input is shutdown");
-        // wrap the input stream so that the close method closes this socket
-        return new SocketInputStream(this, impl.getInputStream());
+        InputStream in = this.in;
+        if (in == null) {
+            // wrap the input stream so that the close method closes this socket
+            in = new SocketInputStream(this, impl.getInputStream());
+            if (!IN.compareAndSet(this, null, in)) {
+                in = this.in;
+            }
+        }
+        return in;
     }
 
     private static class SocketInputStream extends InputStream {
@@ -976,8 +1001,15 @@
             throw new SocketException("Socket is not connected");
         if (isOutputShutdown())
             throw new SocketException("Socket output is shutdown");
-        // wrap the output stream so that the close method closes this socket
-        return new SocketOutputStream(this, impl.getOutputStream());
+        OutputStream out = this.out;
+        if (out == null) {
+            // wrap the output stream so that the close method closes this socket
+            out = new SocketOutputStream(this, impl.getOutputStream());
+            if (!OUT.compareAndSet(this, null, out)) {
+                out = this.out;
+            }
+        }
+        return out;
     }
 
     private static class SocketOutputStream extends OutputStream {