问答详情
源自:3-3 定义通用的返回对象--返回错误信息

由于枚举的值是单例的,在BussinessException中直接传入枚举实例并修改,可能会有并发问题吧?

由于枚举的值是单例的,如果在一个BussinessException传入枚举,再执行setErrMsg修改错误信息。那么在不同线程里所有引用这个枚举的BussinessException中的ErrMsg都会改变。

提问者:webcat 2019-03-28 12:09

个回答

  • weixin_慕丝9246528
    2020-08-29 17:06:24

    @RestController
    @RequestMapping("/user")
    public class UserController {
        
        @GetMapping("/get")
        public String get() {
            return EmBusinessError.PARAMETER_VALIDATION_ERROR.setErrMsg("用户id错误")
                        .getErrMsg();
        }
    
        @GetMapping("/getDefaultMsg")
        public String getDefaultMsg() {
            return EmBusinessError.PARAMETER_VALIDATION_ERROR.getErrMsg();
        }
    }

    setErrMsg这个方法是有问题的。

    假设第一次调用方法get,返回”用户id错误“消息,第二次调用getDefaultMsg方法期望返回“参数错误”这条消息,由于枚举类是单例的,所以在get修改EmBusinessError.PARAMETER_VALIDATION_ERROR的属性后,getDefaultMsg方法还是返回”用户id错误“消息。

  • 宝慕林9319546
    2020-07-20 21:55:42

    有的吧 通过枚举创建的通用错误类型是单列的啊  并发下都调用setErrmsg就有并发问题 没毛病的


  • 少年啊c
    2019-08-01 00:01:11

    这里改的是局部变量吧,没有并发问题


  • 慕圣8322165
    2019-06-27 17:11:14

    反编译枚举类就知道,枚举类的成员变量都是用static final来修饰的,这样修改绝对存在线程安全问题,建议msg不要在这里修改

  • 未完待续4
    2019-03-28 21:17:19

    你怎么修改枚举中的属性?反射?你要用反射那有什么会是安全的?

  • webcat
    2019-03-28 17:29:03

    抱歉,我说错了。枚举不是单例,枚举里面可以定义多个值,每个值都是一个实例,但是这些枚举值是单例的。用枚举实现单例模式也是利用它的值只实例化一次这个特性。

    在这个视频教程中,创建了一个枚举,枚举定义了多个值,又定义了两个枚举属性code,errMsg。

    教程中,在使用某个枚举值的时候,修改了枚举的属性errMsg。这样是不是有线程安全问题?

  • sunbohan00
    2019-03-28 15:56:35

    枚举是实现单例模式的一种方式,但不代表枚举就是单例模式。由于枚举和单例很像,都是将构造方法私有化,且不用考虑序列化的问题。

    多线程并发问题,把Singleton声明成volatile,