src/share/classes/java/net/URL.java

Print this page

        

@@ -1069,11 +1069,11 @@
     }
 
     /**
      * The URLStreamHandler factory.
      */
-    static URLStreamHandlerFactory factory;
+    private static volatile URLStreamHandlerFactory factory;
 
     /**
      * Sets an application's {@code URLStreamHandlerFactory}.
      * This method can be called at most once in a given Java Virtual
      * Machine.

@@ -1104,10 +1104,11 @@
             SecurityManager security = System.getSecurityManager();
             if (security != null) {
                 security.checkSetFactory();
             }
             handlers.clear();
+            // safe publication of URLStreamHandlerFactory with volatile write
             factory = fac;
         }
     }
 
     /**

@@ -1125,13 +1126,15 @@
         URLStreamHandler handler = handlers.get(protocol);
         if (handler == null) {
 
             boolean checkedWithFactory = false;
 
-            // Use the factory (if any)
-            if (factory != null) {
-                handler = factory.createURLStreamHandler(protocol);
+            // Use the factory (if any). Volatile read makes
+            // URLStreamHandlerFactory appear fully initialized to current thread.
+            URLStreamHandlerFactory fac = factory;
+            if (fac != null) {
+                handler = fac.createURLStreamHandler(protocol);
                 checkedWithFactory = true;
             }
 
             // Try java protocol handler
             if (handler == null) {

@@ -1191,12 +1194,12 @@
                     return handler2;
                 }
 
                 // Check with factory if another thread set a
                 // factory since our last check
-                if (!checkedWithFactory && factory != null) {
-                    handler2 = factory.createURLStreamHandler(protocol);
+                if (!checkedWithFactory && (fac = factory) != null) {
+                    handler2 = fac.createURLStreamHandler(protocol);
                 }
 
                 if (handler2 != null) {
                     // The handler from the factory must be given more
                     // importance. Discard the default handler that