自定義枚舉定義可能不是線程安全的。例如,
RoleEnum.java:
package com.threadsafe.bad;
public enum RoleEnum {
ADMIN(1),
DEV(2),
HEAD(3);
private Integer value;
private RoleEnum(Integer role){
this.value=role;
}
public static RoleEnum fromIntegerValue(Integer role){
for(RoleEnum x : values()){
if(x.value == role){
return x;
}
}
return RoleEnum.HEAD;
}
Class<?> buildFromClass;
public void setBuildFromClass(Class<?> classType){
buildFromClass=classType;
}
public Class<?> getBuildFromClass(){
return this.buildFromClass;
}
}
Main.java:
package com.threadsafe.bad;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread threadA = new Thread(){
public void run(){
System.out.println("A started");
RoleEnum role;
role=RoleEnum.fromIntegerValue(1);
System.out.println("A called fromIntegerValue");
role.setBuildFromClass(String.class);
System.out.println("A called setBuildFromClass and start to sleep");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread A: "+role.getBuildFromClass());
}
};
Thread threadB = new Thread(){
public void run(){
System.out.println("B started");
RoleEnum role;
role=RoleEnum.fromIntegerValue(1);
role.setBuildFromClass(Integer.class);
System.out.println("B called fromIntegerValue&setBuildFromClass and Start to sleep");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("B waked up!");
System.out.println("Thread B: "+ role.getBuildFromClass());
}
};
threadA.start();
threadB.start();
}
}
有時輸出將是:
乙開始
b調用它fromIntegerValue &設置BuildFromClass並開始睡覺
一開始
一個名爲fromIntegerValue
一個名爲setBuildFromClass並開始睡覺
線程A:類java.lang.String
乙醒了!
線程B:類java.lang.String < - 我們期望java.lang。整數
有時輸出將是:
一開始
一個名爲fromIntegerValue
一個名爲setBuildFromClass並開始睡覺
乙開始
b調用它fromIntegerValue & setBuildFromClass並開始睡覺
線程A:類java.lang.Integer < - 我們期待java.lang.String中
乙醒了!
線程B:類java.lang.Integer
你是什麼意思的「線程安全」? 'leaveTheBuilding'方法不同步,所以當然可以同時運行多個線程。還是你在說初始化'INSTANCE'? – 2010-03-28 04:20:21
當你說「singleton」時,你的意思是它有可變狀態嗎?在這種情況下,無論如何你都會失敗。 – 2010-03-28 04:46:15
只是我的$ 0.02,但我認爲使用枚舉來強制Singleton模式是代碼混淆。也就是說,我知道布洛赫和其他很多人都認爲這一點,我的評論可能是恐龍的咆哮。 – 2010-03-28 06:53:05