正确理解volatile,同步和AtomicReference等概念?

时间:2013-08-25 11:36:38

标签: java multithreading synchronization volatile atomicreference

我想确保我理解这些概念。解释/确认将对我有所帮助,我相信很多其他程序员。 以下是我对这些概念的理解,这是我的调查结果:

  1. 当您想要在多个线程之间共享变量时,使用Volatile。 a)bwteen声明一个(在线程之间共享)变量volatile和不变量有什么区别? b)在我们从不同的线程访问它时,我们是否应该始终声明它是不稳定的? c)同步volatile变量是否有意义?

  2. AtomicReference是一个包装我们的对象并在其上提供一些原子操作的类(compareAndSet,lazySet和weakCompareAndSet)。这就是全部,没有同步,没有任何东西。 a)声明AtomicReference volatile是否有意义? b)但同步它?,因为AtomicReference.get不同步也没有设置?

  3. 同步是一个概念,意味着对多个线程之间共享的变量进行顺序访问。它可以通过实例和类来完成。可以将同步添加到方法头或代码块中。我希望在这里没有谜。)

  4. 此致 奥勒利安

2 个答案:

答案 0 :(得分:2)

  

a)bwteen声明一个(在线程之间共享)变量volatile和不变量有什么区别?

如果它不是易失性的,那么任何其他线程都不会看到一个线程对它的写入。

  

b)我们是否应该在从不同线程访问它时始终声明它是不稳定的?

除非始终从同步块访问它。

  

c)同步volatile变量是否有意义?

确实如此,但只有在任何同步块之外也可以访问volatile变量。

  

a)声明AtomicReference volatile是否有意义?

如果您打算在运行时更改实例,那肯定会这样做。但是,通常最好有final AtomicReference

  

b)但同步吗?因为AtomicReference.get不是同步的,也不是set?

同步AtomicReference访问失败了其无锁多线程的目的。选择同步或AtomicReference。

答案 1 :(得分:2)

  

当您想要在多个之间共享变量时,使用易失性   线程。 a)宣布a(在...之间共享)有什么区别   线程)变量volatile而不是? b)我们是否应该一直宣布它   我们从不同的线程访问它是不稳定的? c)它是否成功   感觉同步一个volatile变量?

要理解volatile,考虑现代计算机系统硬件的架构是很有用的。

为了提高性能,EACH PROCESSOR OR CORE拥有自己的本地内存缓存。此缓存中存在的数据是特定处理器的本地数据,对其他处理器不可见。此外,几乎任何级别都可以有数据缓存,包括JVM本身。

当您以这种方式考虑线程时,即可以在处理器之间划分的执行单元时,很容易理解Java内存模型的一个非常重要的事实:

无法保证在一个线程中对共享变量所做的更改对于访问同一变量的其他线程(不同步)是可见的。

再次,假设已更新共享变量的数据仍然位于本地处理器缓存中,而其他内核不可用(因此,对其上执行的其他线程不可用)。

volatile关键字为您提供了一种方法,可以保证对共享变量的更改立即写入内存,以便其他线程可以看到它们发生的更改。 Volatile在简单的情况下非常有用,虽然它提供了改进的数据实时性,但它不能保证原子性,因此它不能保证共享变量的竞争条件仍然不会发生。

如果将对象从一个逻辑状态变为另一个逻辑状态需要多个步骤,则必须同步对象状态的访问以保持原子性(更新完全发生或根本不发生)即使状态转换仅涉及声明为volatile的变量。