1

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

  1. 当你想在多个线程之间共享一个变量时使用易失性。a) 声明一个(线程间共享的)变量 volatile 和 not 有什么区别?b) 我们是否应该总是在从不同线程访问它时声明它是 volatile 的?c) 同步 volatile 变量是否有意义?

  2. AtomicReference 是一个包装我们的对象并提供一些原子操作的类(compareAndSet、lazySet 和weakCompareAndSet)。这就是全部,没有同步,什么都没有。a) 声明一个 AtomicReference volatile 有意义吗?b)但是同步呢?,因为 AtomicReference.get 既不同步也不同步?

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

问候, 奥勒良

4

2 回答 2

2

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

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

b) 我们是否应该总是在从不同线程访问它时声明它是 volatile 的?

除非它总是从同步块访问。

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

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

a) 声明一个 AtomicReference volatile 有意义吗?

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

b)但是同步呢?,因为 AtomicReference.get 既不同步也不同步?

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

于 2013-08-25T11:43:53.727 回答
2

当你想在多个线程之间共享一个变量时使用易失性。a) 声明一个(线程间共享的)变量 volatile 和 not 有什么区别?b) 我们是否应该总是在从不同线程访问它时声明它是 volatile 的?c) 同步 volatile 变量是否有意义?

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

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

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

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

同样,假设更新了共享变量的数据仍然位于本地处理器缓存中,其他内核无法使用该缓存(因此,在它们上执行的其他线程也无法使用)。

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

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

于 2013-08-25T12:18:23.223 回答