8054991: sun.font.GlyphList uses broken double-checked locking
authorprr
Mon, 18 Jul 2016 12:15:53 -0700
changeset 39870 55d674017343
parent 39869 0d41bfc821b3
child 39871 a83e3cea8961
8054991: sun.font.GlyphList uses broken double-checked locking Reviewed-by: psadhukhan, aivanov
jdk/src/java.desktop/share/classes/sun/font/GlyphList.java
--- a/jdk/src/java.desktop/share/classes/sun/font/GlyphList.java	Mon Jul 18 09:53:59 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/GlyphList.java	Mon Jul 18 12:15:53 2016 -0700
@@ -28,6 +28,7 @@
 import java.awt.Font;
 import java.awt.font.GlyphVector;
 import java.awt.font.FontRenderContext;
+import java.util.concurrent.atomic.AtomicBoolean;
 import sun.java2d.loops.FontInfo;
 
 /*
@@ -151,8 +152,8 @@
      * occur and if it did, it would just lead to some extra garbage being
      * created.
      */
-    private static GlyphList reusableGL = new GlyphList();
-    private static boolean inUse;
+    private static final GlyphList reusableGL = new GlyphList();
+    private static final AtomicBoolean inUse = new AtomicBoolean();
 
 
     void ensureCapacity(int len) {
@@ -184,24 +185,10 @@
 //     }
 
     public static GlyphList getInstance() {
-        /* The following heuristic is that if the reusable instance is
-         * in use, it probably still will be in a micro-second, so avoid
-         * synchronising on the class and just allocate a new instance.
-         * The cost is one extra boolean test for the normal case, and some
-         * small number of cases where we allocate an extra object when
-         * in fact the reusable one would be freed very soon.
-         */
-        if (inUse) {
+        if (inUse.compareAndSet(false, true)) {
+            return reusableGL;
+        } else {
             return new GlyphList();
-        } else {
-            synchronized(GlyphList.class) {
-                if (inUse) {
-                    return new GlyphList();
-                } else {
-                    inUse = true;
-                    return reusableGL;
-                }
-            }
         }
     }
 
@@ -212,17 +199,10 @@
      * will be discarded so the re-allocation overhead is high.
      */
 //     public static GlyphList getInstance(int sz) {
-//      if (inUse) {
-//          return new GlyphList(sz);
+//      if (inUse.compareAndSet(false, true) {
+//          return reusableGL;
 //      } else {
-//          synchronized(GlyphList.class) {
-//              if (inUse) {
-//                  return new GlyphList();
-//              } else {
-//                  inUse = true;
-//                  return reusableGL;
-//              }
-//          }
+//          return new GlyphList(sz);
 //      }
 //     }
 
@@ -423,7 +403,7 @@
             }
             usePositions = false;
             strikelist = null; // remove reference to the strike list
-            inUse = false;
+            inUse.set(false);
         }
     }