RFR 8029891 : Deadlock detected in java/lang/ClassLoader/deadlock/GetResource.java - A Revival
Brent Christian
brent.christian at oracle.com
Tue May 10 21:56:49 UTC 2016
Hi! Welcome back to 8029891, "Deadlock detected in
java/lang/ClassLoader/deadlock/GetResource.java". Our previous
discussion is at [1].
Briefly, java.util.Properties isa Hashtable, which synchronizes on
itself for any access. System.getProperties() returns the Properties
instance accessed by the system, which any application code might
synchronize on (that's what the test is doing). System properties are a
common way for changing default setting, so it's impractical to expect
the class loading code path not to call System.getProperty.
The fix is to change Properties to store its values in an internal
ConcurrentHashMap, ignoring its Hashtable heritage. In this way,
Properties can be (partly) "de-sychronized", and deadlocks avoided.
While good progress was made during the original code review, all of the
overridden methods in Properties caused an explosion of unnecessary
JavaDoc (see specdiff at [2]). With the recent fix of 8073100 (new
"@hidden" JavaDoc tag), we can now avoid the additional clutter.
Highlights from the previous discussion:
* Specifics of where to remove synchronization: generally, read methods
will be de-synchronized, while write/bulk-read operations will stay
synchronized.
* We considered whether we might be able use special-case code just for
system properties, instead of a general change to Properties. Because a
user is able to supply their own Properties object to
System.setProperties(), which is set as the system properties, and
current behavior reflects changes made to original Properties object, it
would be best to change the Properties class itself.
* Don't leak extra add/remove functionality through returned Enumerations.
* I said I would check on the synchronization of serialization.
writeHashtable() looks okay to me; I expect this is not such a concern
for readHashtable().
A new webrev is here:
http://cr.openjdk.java.net/~bchristi/8029891/webrev.4/
Other changes since the last webrev I posted:
* In readHashtable(), I added a check to validate 'elements', as is done
in Hashtable.
* I have indicated that Iterators from
[keySet|entrySet|values].iterator() no longer fail-fast. While perhaps
not strictly necessary, given the "no guarantees" nature of the
Hashtable spec, my personal preference is to make it clear that
Properties no longer makes a best (or any) effort to throw
ConcurrentModificationException. This should not affect any working
code (which would not see a CME anyway). Given that Properties are
meant to be used as a collection of largely static values, adding
additional code to maintain fail-fast behavior is not warranted.
FWIW, the deadlock code path is now different than what is seen in the
bug report (see [3]). We're now getting hung up on the
Integer.getInteger() call to get MAX_ARITY on line 60 of
MethodHandleImpl [4].
Thanks,
-Brent
1. http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-May/033147.html
2.
http://cr.openjdk.java.net/~bchristi/8029891/webrev.3/specdiff-plain/Properties.html
3. http://cr.openjdk.java.net/~bchristi/8029891/webrev.4/NewDeadlock.txt
4.
http://hg.openjdk.java.net/jdk9/dev/jdk/file/1049321b86cb/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
More information about the core-libs-dev
mailing list