Applying Jason Madden's patch from LANG-334 to provide enums.Enum with optimized thread safety. As Jason's used this in production I think it's fair to use it rather than the simpler Collections.synchronizedMap(..). I've also applied the patch to the enum.Enum

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@572930 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Henri Yandell 2007-09-05 10:13:49 +00:00
parent 2ca0eff93c
commit 60fe05eb7a
2 changed files with 33 additions and 15 deletions

View File

@ -256,7 +256,11 @@ public abstract class Enum implements Comparable, Serializable {
/**
* <code>Map</code>, key of class name, value of <code>Entry</code>.
*/
private static final Map cEnumClasses = new WeakHashMap();
private static Map cEnumClasses
// LANG-334: To avoid exposing a mutating map,
// we copy it each time we add to it. This is cheaper than
// using a synchronized map since we are almost entirely reads
= new WeakHashMap();
/**
* The string representation of the Enum.
@ -350,11 +354,16 @@ public abstract class Enum implements Comparable, Serializable {
throw new IllegalArgumentException("getEnumClass() must return a superclass of this class");
}
// create entry
Entry entry = (Entry) cEnumClasses.get(enumClass);
if (entry == null) {
entry = createEntry(enumClass);
cEnumClasses.put(enumClass, entry);
Entry entry;
synchronized( Enum.class ) { // LANG-334
// create entry
entry = (Entry) cEnumClasses.get(enumClass);
if (entry == null) {
entry = createEntry(enumClass);
Map myMap = new WeakHashMap( cEnumClasses );
myMap.put(enumClass, entry);
cEnumClasses = myMap;
}
}
if (entry.map.containsKey(name)) {
throw new IllegalArgumentException("The Enum name must be unique, '" + name + "' has already been added");

View File

@ -302,7 +302,11 @@ public abstract class Enum implements Comparable, Serializable {
/**
* <code>Map</code>, key of class name, value of <code>Entry</code>.
*/
private static final Map cEnumClasses = new WeakHashMap();
private static Map cEnumClasses
// LANG-334: To avoid exposing a mutating map,
// we copy it each time we add to it. This is cheaper than
// using a synchronized map since we are almost entirely reads
= new WeakHashMap();
/**
* The string representation of the Enum.
@ -345,7 +349,7 @@ public abstract class Enum implements Comparable, Serializable {
* <p>Restrictive constructor.</p>
*/
protected Entry() {
super();
super();
}
}
@ -396,11 +400,16 @@ public abstract class Enum implements Comparable, Serializable {
throw new IllegalArgumentException("getEnumClass() must return a superclass of this class");
}
// create entry
Entry entry = (Entry) cEnumClasses.get(enumClass);
if (entry == null) {
entry = createEntry(enumClass);
cEnumClasses.put(enumClass, entry);
Entry entry;
synchronized( Enum.class ) { // LANG-334
// create entry
entry = (Entry) cEnumClasses.get(enumClass);
if (entry == null) {
entry = createEntry(enumClass);
Map myMap = new WeakHashMap( cEnumClasses );
myMap.put(enumClass, entry);
cEnumClasses = myMap;
}
}
if (entry.map.containsKey(name)) {
throw new IllegalArgumentException("The Enum name must be unique, '" + name + "' has already been added");