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:
parent
2ca0eff93c
commit
60fe05eb7a
|
@ -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.
|
||||
|
@ -349,12 +353,17 @@ public abstract class Enum implements Comparable, Serializable {
|
|||
if (ok == false) {
|
||||
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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,12 +399,17 @@ public abstract class Enum implements Comparable, Serializable {
|
|||
if (ok == false) {
|
||||
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");
|
||||
|
|
Loading…
Reference in New Issue