默认

[已回复] 求助关于MobileIMSDK服务端单例模式并发安全问题

查看数: 94540 | 评论数: 20 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2021-08-02 10:52

正文摘要:

bug:mobileSDK 大量使用了单例模式,但是并没有双重效验机制,今天正好碰到了这个并发问题,导致在线用户某一时刻同时上线出现的bug; 望作者修改! 示例: public static OnlineProcessor getInstance() { & ...

评论

JackJiang 发表于 3 年前
引用:csj 发表于 2021-08-16 10:34
楼主的写法只会第一次初始化 OnlineProcessor 时加锁,应该没有多大性能开销,但是会不会出现指令重排的 ...

加个volatile更严谨一些
csj 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 11:09
你具体描述一下:“导致在线用户某一时刻同时上线出现的bug”?

另外,你这样粗暴的 synchronized,肯定 ...

楼主的写法只会第一次初始化 OnlineProcessor 时加锁,应该没有多大性能开销,但是会不会出现指令重排的问题,导致调用时空指针。要不要加个volatile禁止指令重排   private volatile static OnlineProcessor instance
JackJiang 发表于 3 年前
引用:要你命三千 发表于 2021-08-02 15:04
我建议作者自己可以试一下

理论上确实有可能出现你说的情况,但奇怪的是,这么多年更新以来,在JDK1.8及以下的版本中,从未发生过问题,一直工作的好好的。。。 这也导致我一直没把它当回事。
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 14:54
你说的也有道理,我接受你的建议。因为目前为止主流一直都是jdk1.8,且经过大量使用确实没有出现过你说的 ...

具体的流程就在上面我回复的第一帖,有个场景....
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 14:54
你说的也有道理,我接受你的建议。因为目前为止主流一直都是jdk1.8,且经过大量使用确实没有出现过你说的 ...

我建议作者自己可以试一下
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 14:54
你说的也有道理,我接受你的建议。因为目前为止主流一直都是jdk1.8,且经过大量使用确实没有出现过你说的 ...

    //之前的代码
    private static OnlineProcessor instance = null;
    //改为
    private static OnlineProcessor instance = new OnlineProcessor();
  这样也是可以的
JackJiang 发表于 3 年前
引用:要你命三千 发表于 2021-08-02 14:50
现在在工作,而且目前没有jdk8的环境,我安找我发布的贴的优化后解决了这个问题,所以现在是测试不了了, ...

你说的也有道理,我接受你的建议。因为目前为止主流一直都是jdk1.8,且经过大量使用确实没有出现过你说的情况,所以一直也没有在意这个,但不能排除更高版本的jdk有可能调用机制有变化,我会记录一下,持续关注这个问题。
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 11:09
你具体描述一下:“导致在线用户某一时刻同时上线出现的bug”?

另外,你这样粗暴的 synchronized,肯定 ...

我觉得没有问题呀,synchronized只是在第一次 为null的时候才会有效啊,所以好像不会影响什么问题吧?还是我没理解到?
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 14:48
把JDK降到1.8后,你看看效果,你现在就去试试

现在在工作,而且目前没有jdk8的环境,我安找我发布的贴的优化后解决了这个问题,所以现在是测试不了了,而且我觉得这样的单例模式在jdk8下也会出现线程安全问题。
JackJiang 发表于 3 年前

把JDK降到1.8后,你看看效果,你现在就去试试
JackJiang 发表于 3 年前
引用:要你命三千 发表于 2021-08-02 14:16
问题就在于两个客户端在服务端启动的一瞬间上线了,同时调用OnlineProcessor的getInstance()方法导致的 ...

你上面回复了好几贴,我还是没弄明白你说的并发问题,具体是什么问题?我说蒙逼了。。。
你说的两个实例,这个截图上貌似也没看出来什么并发问题或者你说的两个实例

或者我没有理解你的意思?
JackJiang 发表于 3 年前
引用:要你命三千 发表于 2021-08-02 14:16
问题就在于两个客户端在服务端启动的一瞬间上线了,同时调用OnlineProcessor的getInstance()方法导致的 ...

别说2个客户端,200个我都刻意试过,没遇到过你说的情况。你的JDK用的是什么版本?
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 12:20
两上实例肯定不对的,你排查一下,为什么会搞出两个实例。你服务端是怎么部署的,放在Spring boot里的吗 ...

问题就在于两个客户端在服务端启动的一瞬间上线了,同时调用OnlineProcessor的getInstance()方法导致的并发 问题
JackJiang 发表于 3 年前

两上实例肯定不对的,你排查一下,为什么会搞出两个实例。你服务端是怎么部署的,放在Spring boot里的吗,我记得之前有人Spring boot里bean没用明白,就重复实例了
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 11:52
instance 不一致?

你指的是出现了两个不同的OnlineProcessor实例?

JackJiang 发表于 3 年前
引用:要你命三千 发表于 2021-08-02 11:37
场景:1 两个客户端登录成功,2 服务端下线,客户端自动登录启动,3 启动服务端,两个客户端同时登录,由 ...

instance 不一致?

你指的是出现了两个不同的OnlineProcessor实例?
要你命三千 发表于 3 年前
引用:JackJiang 发表于 2021-08-02 11:09
你具体描述一下:“导致在线用户某一时刻同时上线出现的bug”?

另外,你这样粗暴的 synchronized,肯定 ...

场景:1 两个客户端登录成功,2 服务端下线,客户端自动登录启动,3 启动服务端,两个客户端同时登录,由于netty下的异步响应有几率导致两个获取的instance 不一致,我通过输出hashcode发现的不一致,目前只在第一次启动的时候出现这样的问题。

返回顶部