How thread-safe is enum in java?

后端 未结 4 1907
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 08:01

How thread-safe is enum in java? I am implementing a Singleton using enum (as per Bloch\'s Effective Java), should I worry at all about thread safety for my singleton enum?

4条回答
  •  悲哀的现实
    2020-11-29 08:45

    Customized Enum Definition may be not thread safe. For example,

    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();
    
    
           }
    
    }
    

    Sometimes the output will be:

    B started

    B called fromIntegerValue&setBuildFromClass and Start to sleep

    A started

    A called fromIntegerValue

    A called setBuildFromClass and start to sleep

    Thread A: class java.lang.String

    B waked up!

    Thread B: class java.lang.String <-We expect java.lang.Integer

    Sometimes the output will be:

    A started

    A called fromIntegerValue

    A called setBuildFromClass and start to sleep

    B started

    B called fromIntegerValue&setBuildFromClass and Start to sleep

    Thread A: class java.lang.Integer <-We expect java.lang.String

    B waked up!

    Thread B: class java.lang.Integer

提交回复
热议问题