是否有一种情况我们不会将volatile用于线程之间共享的对象的类成员?我的理解是volatile关键字确保对象值不被线程缓存,但始终从内存中读取,但不将其标记为volatile,并不意味着它总是被线程缓存。所以我的问题是,我们可以通过不将这样的类标记为volatile来保证任何东西,还是代码可以随机行为开放?
编辑:我明白使用volatile代替一切并不能保证我逻辑的正确性。我的问题更多是理论性的,是我尝试理解Java内存模型的。
答案 0 :(得分:3)
至少 immutable 对象永远不需要任何类型的任何同步。 因此,对于不可变类的字段使用 volatile 是没有意义的。
答案 1 :(得分:3)
首先,您不应该根据缓存来解释并发性。从版本2开始,Java内存模型更正式,要求更低。所以,在订单之前,它就是发生的事情。
如果您需要对某个变量进行并发访问,则必须按顺序排序写入和读取。这是最重要的事情。易失性只是这种排序的一种实现方式。
因此,您可以使用发生在语义之前的任何操作,而不是volatile。来自JLS:
监视器上的解锁发生在每次后续锁定之前 监视。
对线程的start()调用发生在 - 之前的任何操作之前 开始了。
线程中的所有操作都发生在任何其他线程成功之前 从该线程上的join()返回。
任何对象的默认初始化发生在任何其他对象之前 程序的动作(默认写入除外)。
答案 2 :(得分:0)
如果你没有将变量声明为volatile,并且在访问之前不进行任何类型的互斥锁定,那么是的,你总是会让自己面临不可预测的行为和竞争条件/死锁。