Tùy chỉnh Enum Definition có thể không phải là chủ đề an toàn. Ví dụ,
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();
}
}
Đôi khi đầu ra sẽ là:
B bắt đầu
B gọi fromIntegerValue & bộ BuildFromClass và Start để ngủ
Một bắt đầu
Một gọi fromIntegerValue
Một gọi setBuildFromClass và bắt đầu ngủ
Chủ đề A: lớp java.lang.String
B đều thức dậy!
Chủ đề B: lớp java.lang.String < -Chúng tôi hy vọng java.lang.Integer
Đôi khi đầu ra sẽ là:
Một bắt đầu
Một gọi fromIntegerValue
Một gọi setBuildFromClass và bắt đầu ngủ
B bắt đầu
B gọi fromIntegerValue & setBuildFromClass và Start để ngủ
Chủ đề A: lớp java.lang.Integer < -Chúng tôi mong đợi java.lang.String
B đều thức dậy!
Thread B: lớp java.lang.Integer
Nguồn
2014-10-17 11:02:36
Bạn có ý nghĩa gì bởi "an toàn chỉ"? Phương thức 'leaveTheBuilding' không được đồng bộ hóa, do đó, tất nhiên nó có thể được chạy bởi nhiều luồng cùng một lúc. Hay bạn đang nói về việc khởi tạo 'INSTANCE'? –
Khi bạn nói "singleton", bạn có nghĩa là nó có trạng thái có thể thay đổi không? Trong trường hợp đó, bạn đang ở trên một kẻ thất bại anyway. –
Chỉ cần $ 0,02 của tôi, nhưng tôi nghĩ rằng bằng cách sử dụng một enum để thực thi mô hình Singleton là obfuscation mã. Điều đó nói rằng, tôi biết Bloch cùng với nhiều người khác cho thấy nó và bình luận của tôi có thể là sủa của một con khủng long. –