Enum personalizada La definición puede no ser segura para subprocesos. Por ejemplo,
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();
}
}
veces, la salida será:
B comenzó
B llama fromIntegerValue & conjunto BuildFromClass y empezar a dormir
Un comenzó
Un llamados fromIntegerValue
Un llamados setBuildFromClass y empezar a dormir
Tema A: java.lang.String clase
B despertado!
Subproceso B: clase java.lang.String < -Esperamos java.lang.Entero
veces, la salida será:
Un comenzó
Un llamado fromIntegerValue
Un llamado setBuildFromClass y empezar a dormir
B comenzó
B llamada fromIntegerValue & setBuildFromClass y empezar a dormir
Tema A: clase java.lang.Integer < -Esperamos java.lang.String
B despertado!
Tema B: clase java.lang.Integer
¿Qué quiere decir con "thread-safe"? El método 'leaveTheBuilding' no está sincronizado, por lo que, por supuesto, podría ser ejecutado por múltiples hilos simultáneamente. ¿O estás hablando de inicializar el 'INSTANCE'? –
Cuando dice "singleton", ¿quiere decir que tiene estado mutable? En ese caso, estás en un perdedor de todos modos. –
Solo mi $ 0.02, pero creo que usar una enumeración para hacer cumplir el patrón de Singleton es una ofuscación de código. Dicho esto, sé que Bloch junto con muchos otros lo sugieren y mi comentario puede ser el ladrido de un dinosaurio. –