-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
5.0
-
generic
-
generic
We have some problems with the class sun/awt/AppContext. This
class has a static field:
private static MostRecentThreadAppContext
mostRecentThreadAppContext = null;
.. that serves as a cache when people call the static method
getAppContext(). The class MostRecentThreadAppContext has two
fields
final Thread thread;
final AppContext appContext;
that are set in the constructor of that class. The cache seems
to work like this, getAppContext has code:
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
if ((recent != null) && (recent.thread == currentThread)) {
appContext = recent.appContext; // Cache hit
} else
...
and if we don't get a hit, we later on in the same method do:
mostRecentThreadAppContext =
new MostRecentThreadAppContext(currentThread, context);
The field mostRecentThreadAppContext is also referred to from the
method dispose().
I'm not 100% certain of the Java Memory Model and its whereabouts,
but in my view, this cache is not safe at all on hardware with
a relaxed memory model. There is no guarantee that the constructor
store of the field appContext will be visible to other threads before
the store of mostRecentThreadContext. Therefore, the method getAppContext
might see a mostRecentThreadAppContext that is non null and has
the thread-field set, but also a appContext that might be null (the
store of that field has not been visible yet). The solution in
my view is to encapsulate all reads and writes of the
mostRecentThreadAppContext field with synchronization.
class has a static field:
private static MostRecentThreadAppContext
mostRecentThreadAppContext = null;
.. that serves as a cache when people call the static method
getAppContext(). The class MostRecentThreadAppContext has two
fields
final Thread thread;
final AppContext appContext;
that are set in the constructor of that class. The cache seems
to work like this, getAppContext has code:
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
if ((recent != null) && (recent.thread == currentThread)) {
appContext = recent.appContext; // Cache hit
} else
...
and if we don't get a hit, we later on in the same method do:
mostRecentThreadAppContext =
new MostRecentThreadAppContext(currentThread, context);
The field mostRecentThreadAppContext is also referred to from the
method dispose().
I'm not 100% certain of the Java Memory Model and its whereabouts,
but in my view, this cache is not safe at all on hardware with
a relaxed memory model. There is no guarantee that the constructor
store of the field appContext will be visible to other threads before
the store of mostRecentThreadContext. Therefore, the method getAppContext
might see a mostRecentThreadAppContext that is non null and has
the thread-field set, but also a appContext that might be null (the
store of that field has not been visible yet). The solution in
my view is to encapsulate all reads and writes of the
mostRecentThreadAppContext field with synchronization.