Java 可以使用volatile和;原子整数“;保证线程安全?

Java 可以使用volatile和;原子整数“;保证线程安全?,java,multithreading,atomic,volatile,Java,Multithreading,Atomic,Volatile,如果我有 private volatile AtomicInteger atomInt = new AtomicInteger(3); 在方法中,我的用法是atomInt.incrementAndGet() 由于我使用的是AtomicInteger,因此它将避免“线程干扰”。然后我使用volatile,因此它将保证所有线程中变量的一致视图。这是否意味着我已经获得了完全的线程安全性,还是仍然存在“内存一致性问题” 由于在中使用了“reduce”,我感到困惑,因此它暗示我仍然有机会,但我想不起来:

如果我有

private volatile AtomicInteger atomInt = new AtomicInteger(3);
在方法中,我的用法是
atomInt.incrementAndGet()

由于我使用的是
AtomicInteger
,因此它将避免“线程干扰”。然后我使用volatile,因此它将保证所有线程中变量的一致视图。这是否意味着我已经获得了完全的线程安全性,还是仍然存在“内存一致性问题”

由于在中使用了“reduce”,我感到困惑,因此它暗示我仍然有机会,但我想不起来:

使用易失性变量可以降低内存一致性的风险 错误,因为对易失性变量的任何写入都会建立 发生在与该对象的后续读取的关系之前 变数

然后我使用的是
volatile
,因此它将保证所有线程中变量的一致视图

原子变量已经保证了线程安全<如果不重新分配变量,则代码>volatile是多余的。您可以在此处将
volatile
替换为
final

private final AtomicInteger atomInt = new AtomicInteger(3);
这是否意味着我已经获得了完全的线程安全性,还是仍然存在“内存一致性问题”

现在,它是绝对线程安全的。变量可能不会出现“内存一致性问题”。但是使用适当的线程安全组件并不意味着整个类/程序是线程安全的。如果它们之间的交互不正确,可能会出现问题

使用易失性变量可以降低内存一致性错误的风险

volatile
变量只能保证可见性。他们不能保证

如我所写(强调):

volatile
变量很方便,但它们有局限性。易失性变量最常见的用途是作为完成、中断或状态标志。Volatile变量可用于其他类型的状态信息,但在尝试此操作时需要更加小心。例如,volatile的语义不足以使增量操作(
count++
)原子化,除非您可以保证变量仅从单个线程写入

仅当满足以下所有条件时,才能使用可变变量:

  • 对变量的写入不依赖于其当前值,或者您可以确保只有一个线程更新该值
  • 变量不参与与其他状态变量的不变量
  • 在访问变量时,无需出于任何其他原因进行锁定

从软件包的文档中:

  • get
    具有读取
    volatile
    变量的记忆效果
  • set
    具有写入(分配)一个
    volatile
    变量的记忆效果
然后我使用的是
volatile
,因此它将保证所有线程中变量的一致视图

原子变量已经保证了线程安全<如果不重新分配变量,则代码>volatile是多余的。您可以在此处将
volatile
替换为
final

private final AtomicInteger atomInt = new AtomicInteger(3);
这是否意味着我已经获得了完全的线程安全性,还是仍然存在“内存一致性问题”

现在,它是绝对线程安全的。变量
可能不会出现“内存一致性问题”。但是使用适当的线程安全组件并不意味着整个类/程序是线程安全的。如果它们之间的交互不正确,可能会出现问题

使用易失性变量可以降低内存一致性错误的风险

volatile
变量只能保证可见性。他们不能保证

如我所写(强调):

volatile
变量很方便,但它们有局限性。易失性变量最常见的用途是作为完成、中断或状态标志。Volatile变量可用于其他类型的状态信息,但在尝试此操作时需要更加小心。例如,volatile的语义不足以使增量操作(
count++
)原子化,除非您可以保证变量仅从单个线程写入

仅当满足以下所有条件时,才能使用可变变量:

  • 对变量的写入不依赖于其当前值,或者您可以确保只有一个线程更新该值
  • 变量不参与与其他状态变量的不变量
  • 在访问变量时,无需出于任何其他原因进行锁定

从软件包的文档中:

  • get
    具有读取
    volatile
    变量的记忆效果
  • set
    具有写入(分配)一个
    volatile
    变量的记忆效果

Volatile并不意味着可以看到对变量的更改。但是在这种情况下,您不应该更改变量所持有的引用

这看起来很奇怪,你想让一个原子对象的引用不稳定。atomicinteger类的全部要点是提供一种安全地访问和更改整数值的方法。使某个变量不稳定的唯一原因是您打算覆盖它的值。当您可以使用原子整数的实例方法更新其值时,为什么要覆盖对原子整数的引用

这就是为什么您会得到建议,让这个变量成为final而不是volatile。使变量final固定引用,使其不能更改,同时确保引用继续