# HG changeset patch # User prr # Date 1468869353 25200 # Node ID 55d6740173431ab1a55614775cbe8d76134d09ea # Parent 0d41bfc821b3a1d3163ffe88588f76a28223472b 8054991: sun.font.GlyphList uses broken double-checked locking Reviewed-by: psadhukhan, aivanov diff -r 0d41bfc821b3 -r 55d674017343 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); } }