引用:csj 发表于 2021-08-16 10:34 加个volatile更严谨一些 |
引用:JackJiang 发表于 2021-08-02 11:09 楼主的写法只会第一次初始化 OnlineProcessor 时加锁,应该没有多大性能开销,但是会不会出现指令重排的问题,导致调用时空指针。要不要加个volatile禁止指令重排 private volatile static OnlineProcessor instance |
引用:要你命三千 发表于 2021-08-02 15:04 理论上确实有可能出现你说的情况,但奇怪的是,这么多年更新以来,在JDK1.8及以下的版本中,从未发生过问题,一直工作的好好的。。。 这也导致我一直没把它当回事。 |
引用:JackJiang 发表于 2021-08-02 14:54 具体的流程就在上面我回复的第一帖,有个场景.... |
引用:JackJiang 发表于 2021-08-02 14:54 我建议作者自己可以试一下 |
引用:JackJiang 发表于 2021-08-02 14:54 //之前的代码 private static OnlineProcessor instance = null; //改为 private static OnlineProcessor instance = new OnlineProcessor(); 这样也是可以的 |
引用:要你命三千 发表于 2021-08-02 14:50 你说的也有道理,我接受你的建议。因为目前为止主流一直都是jdk1.8,且经过大量使用确实没有出现过你说的情况,所以一直也没有在意这个,但不能排除更高版本的jdk有可能调用机制有变化,我会记录一下,持续关注这个问题。 |
引用:JackJiang 发表于 2021-08-02 11:09 我觉得没有问题呀,synchronized只是在第一次 为null的时候才会有效啊,所以好像不会影响什么问题吧?还是我没理解到? |
引用:JackJiang 发表于 2021-08-02 14:48 现在在工作,而且目前没有jdk8的环境,我安找我发布的贴的优化后解决了这个问题,所以现在是测试不了了,而且我觉得这样的单例模式在jdk8下也会出现线程安全问题。 |
引用:要你命三千 发表于 2021-08-02 14:40 把JDK降到1.8后,你看看效果,你现在就去试试 |
引用:要你命三千 发表于 2021-08-02 14:16 你上面回复了好几贴,我还是没弄明白你说的并发问题,具体是什么问题?我说蒙逼了。。。 你说的两个实例,这个截图上貌似也没看出来什么并发问题或者你说的两个实例 或者我没有理解你的意思? |
引用:要你命三千 发表于 2021-08-02 14:16 别说2个客户端,200个我都刻意试过,没遇到过你说的情况。你的JDK用的是什么版本? |
引用:JackJiang 发表于 2021-08-02 12:20 问题就在于两个客户端在服务端启动的一瞬间上线了,同时调用OnlineProcessor的getInstance()方法导致的并发 问题 |
两上实例肯定不对的,你排查一下,为什么会搞出两个实例。你服务端是怎么部署的,放在Spring boot里的吗,我记得之前有人Spring boot里bean没用明白,就重复实例了 |
引用:JackJiang 发表于 2021-08-02 11:52 对 |
引用:要你命三千 发表于 2021-08-02 11:37 instance 不一致? 你指的是出现了两个不同的OnlineProcessor实例? |
引用:JackJiang 发表于 2021-08-02 11:09 场景:1 两个客户端登录成功,2 服务端下线,客户端自动登录启动,3 启动服务端,两个客户端同时登录,由于netty下的异步响应有几率导致两个获取的instance 不一致,我通过输出hashcode发现的不一致,目前只在第一次启动的时候出现这样的问题。 |