如果一个单例类的变量 只有一个线程A进行修改 其他B C D线程对其进行读取 需要加上Volatile保证其可见性吗?
如果你的目的是读写不冲突,那么最好的解决方法就是加上读写锁,至于加不加Valotile跟这个无关,就算你加上Valotile也只是防止指令重排序而已。
那么什么时候会用到这个Valotile呢?当你对并发要求十分高的时候,什么意思呢?
比如你使用双重检查锁的时候,现在有两个线程,其中一个线程拿到锁开始实例变量的初始化过程。
假设这个初始化过程分为好几步,由于CPU的重排序效果,导致生成实例变量的塞入内存时(其中一步)还没有完全初始化完成(其他几步也参与完成初始化)。
那么此时线程二进入获取实例变量的方法,首先判断实例变量是否为空的返回值将是false,那么它会尝试去内存中拿到这个变量,正如上文所说的的,它拿到的这个变量将是一个中间的状态,因此会出现问题。
为了避免该问题,就需要加上Volotile来防止指令重排序,使初始化过程按步骤进行,内存中的内容一定不是一个中间状态的结果。
但还是那句话,我们真的需要这么极致的防高并发操作么?我想这种情况很难出现。。。所以很多单例的实现中并没有提到这一点。
8 回答6.4k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
1 回答2.2k 阅读✓ 已解决
3 回答1.6k 阅读✓ 已解决
一般,最好的单例模式是枚举,这是effective java 中的推荐。
如果枚举没办法满足要求,则推荐延迟初始化占位符这种方式。更加清晰,明了。DCL那种方式容易让人犯错。