Does this look like a race?
David Holmes
david.holmes at oracle.com
Wed Aug 13 07:55:35 UTC 2014
On 13/08/2014 1:01 AM, Andrew Haley wrote:
> (Please forgive me if this should go to the AWT list or somesuch. It
> seems to me like this is not really a graphics-related issue, but one
> of Java concurrency.)
>
> This is in JDK9, sun.font.GlyphList. There is a non-volatile boolean
> inUse, and it is not always written in a synchronized block. It is
> used to allow exclusive access to a singleton instance.
>
> It seems to me that, at a minimum, inUse should be volatile, or e.g.
> strikelist might be overwritten to null after some other thread has
> started using this GlyphList. Do you agree?
Yes, either inUse needs to be volatile and used in a way that ensures
the correct happens-before relationships, or dispose() needs to do all
modifications to the shared instance inside a synchronized block and
clear inUse in that block.
David
> Thanks,
> Andrew.
>
>
> /* This scheme creates a singleton GlyphList which is checked out
> * for use. Callers who find its checked out create one that after use
> * is discarded. This means that in a MT-rendering environment,
> * there's no need to synchronise except for that one instance.
> * Fewer threads will then need to synchronise, perhaps helping
> * throughput on a MP system. If for some reason the reusable
> * GlyphList is checked out for a long time (or never returned?) then
> * we would end up always creating new ones. That situation should not
> * 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;
>
> ...
>
> 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) {
> return new GlyphList();
> } else {
> synchronized(GlyphList.class) {
> if (inUse) {
> return new GlyphList();
> } else {
> inUse = true;
> return reusableGL;
> }
> }
> }
> }
>
> ...
>
> /* There's a reference equality test overhead here, but it allows us
> * to avoid synchronizing for GL's that will just be GC'd. This
> * helps MP throughput.
> */
> public void dispose() {
> if (this == reusableGL) {
> if (graybits != null && graybits.length > MAXGRAYLENGTH) {
> graybits = null;
> }
> usePositions = false;
> strikelist = null; // remove reference to the strike list
> inUse = false;
> }
> }
>
More information about the core-libs-dev
mailing list