8185093: Expensive multi-core choke point when any graphics objects are created
authorserb
Fri, 04 Aug 2017 18:39:23 -0700
changeset 47169 15fbd6b6b8b0
parent 47168 7d629cc65545
child 47170 ac621266a4b8
8185093: Expensive multi-core choke point when any graphics objects are created Reviewed-by: prr, flar
jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
--- a/jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java	Thu Aug 03 14:55:48 2017 +0530
+++ b/jdk/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java	Fri Aug 04 18:39:23 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -54,7 +54,6 @@
  */
 
 public abstract class GraphicsEnvironment {
-    private static GraphicsEnvironment localEnv;
 
     /**
      * The headless state of the Toolkit and GraphicsEnvironment
@@ -74,53 +73,60 @@
     }
 
     /**
-     * Returns the local {@code GraphicsEnvironment}.
-     * @return the local {@code GraphicsEnvironment}
+     * Lazy initialization of local graphics environment using holder idiom.
      */
-    public static synchronized GraphicsEnvironment getLocalGraphicsEnvironment() {
-        if (localEnv == null) {
-            localEnv = createGE();
+    private static final class LocalGE {
+
+        /**
+         * The instance of the local {@code GraphicsEnvironment}.
+         */
+        static final GraphicsEnvironment INSTANCE = createGE();
+
+        /**
+         * Creates and returns the GraphicsEnvironment, according to the
+         * system property 'java.awt.graphicsenv'.
+         *
+         * @return the graphics environment
+         */
+        private static GraphicsEnvironment createGE() {
+            GraphicsEnvironment ge;
+            String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null));
+            try {
+//              long t0 = System.currentTimeMillis();
+                Class<?> geCls;
+                try {
+                    // First we try if the bootstrap class loader finds the
+                    // requested class. This way we can avoid to run in a privileged
+                    // block.
+                    geCls = Class.forName(nm);
+                } catch (ClassNotFoundException ex) {
+                    // If the bootstrap class loader fails, we try again with the
+                    // application class loader.
+                    ClassLoader cl = ClassLoader.getSystemClassLoader();
+                    geCls = Class.forName(nm, true, cl);
+                }
+                ge = (GraphicsEnvironment)geCls.getConstructor().newInstance();
+//              long t1 = System.currentTimeMillis();
+//              System.out.println("GE creation took " + (t1-t0)+ "ms.");
+                if (isHeadless()) {
+                    ge = new HeadlessGraphicsEnvironment(ge);
+                }
+            } catch (ClassNotFoundException e) {
+                throw new Error("Could not find class: "+nm);
+            } catch (ReflectiveOperationException | IllegalArgumentException e) {
+                throw new Error("Could not instantiate Graphics Environment: "
+                        + nm);
+            }
+            return ge;
         }
-
-        return localEnv;
     }
 
     /**
-     * Creates and returns the GraphicsEnvironment, according to the
-     * system property 'java.awt.graphicsenv'.
-     *
-     * @return the graphics environment
+     * Returns the local {@code GraphicsEnvironment}.
+     * @return the local {@code GraphicsEnvironment}
      */
-    private static GraphicsEnvironment createGE() {
-        GraphicsEnvironment ge;
-        String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null));
-        try {
-//          long t0 = System.currentTimeMillis();
-            Class<?> geCls;
-            try {
-                // First we try if the bootstrap class loader finds the
-                // requested class. This way we can avoid to run in a privileged
-                // block.
-                geCls = Class.forName(nm);
-            } catch (ClassNotFoundException ex) {
-                // If the bootstrap class loader fails, we try again with the
-                // application class loader.
-                ClassLoader cl = ClassLoader.getSystemClassLoader();
-                geCls = Class.forName(nm, true, cl);
-            }
-            ge = (GraphicsEnvironment)geCls.getConstructor().newInstance();
-//          long t1 = System.currentTimeMillis();
-//          System.out.println("GE creation took " + (t1-t0)+ "ms.");
-            if (isHeadless()) {
-                ge = new HeadlessGraphicsEnvironment(ge);
-            }
-        } catch (ClassNotFoundException e) {
-            throw new Error("Could not find class: "+nm);
-        } catch (ReflectiveOperationException | IllegalArgumentException e) {
-            throw new Error("Could not instantiate Graphics Environment: "
-                            + nm);
-        }
-        return ge;
+    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
+        return LocalGE.INSTANCE;
     }
 
     /**