这是perpertual “冗长-if或switch”困境的变化......线程安全
使用包含长一个静态方法(超过一打的考虑多线程应用程序条件)if
语句,这相应地将检查对象的类型,并返回一个值,即像
public static String checkType(Class<?> type)
{
if (type == A.class)
{
return aString;
}
else if (type == B.class)
{
return bString;
}
...
else if (type == z.class)
{
return zString;
}
}
显然switch语句是不能直接适用在这里,所以共同的图案是有一个enum
并调用它valueOf()
,即d ø类似
public enum Strings
{
A(aString), B(bString), ..., Z(zString)
private final String value;
private Strings(String value)
{
this.value = value;
}
public String value()
{
return this.value;
}
}
所以,checkType()
可以重新写为
public static String checkType(Class<?> type)
{
return Strings.valueOf(getActualTypeName(type.getClass().getName())).value();
}
具有用于在生产代码和非原始类型一些字符串处理加入null
值相应的检查,则getActualTypeName()
方法内,从"class java.lang.Long"
等字符串中检索实际的类型名称(对于基元,getName()
方法返回期望的字符串,例如“long"
)。
但是,如果valueOf()
不是线程安全的,这不会在并行环境下工作。这同样适用于使用(正常)Map
对象,可能这两个选择都是相同的模式的变种,因为enum.valueOf()
显然是基于
Enum.valueOf(Class<T> enumType, String name)
这就要求
enumType.enumConstantDirectory().get(name);
在
Class.java
类
。
每次调用enumConstantDirectory()
方法时,都会返回一个新的HashMap
,它由values()
数组的副本创建。
这是线程安全吗?
如果它扩展Enum.valueOf() ,那么它查找非同步映射。查看Enum.valueOf()方法的来源;它调用enumType.enumConstantDirectory()。get(name)。 – PNS 2012-08-16 12:44:05
@PNS如果你看得更深一些,你会看到'enumConstantDirectory'(变量)是易变的,所以这提供了足够的保证,以确保映射安全地发布,并且在构建之后永远不会改变。最糟糕的情况是地图不止一次被创建,但是因为它的创建基于最终状态,所以它是确定性的,所以所使用的懒惰模式使得它是线程安全的。 – assylias 2012-08-16 12:47:03
你是对的,它似乎是安全的。哪个好! :-) – PNS 2012-08-16 12:54:00