在Java中是不是原子?

Sta*_*kER 8 java jvm atomic atomicity

我知道如果没有锁定,增量操作在C++中不是原子操作.

JVM是否会对其iinc指令实现添加任何锁定?

Nar*_*hai 18

不,这不对

  • 检索c的当前值.
  • 将检索的值增加1.
  • 将增加的值存储在c中.

用于原子性和线程干扰的Java文档

您需要使用synchronized关键字或使用AtomicXXXThread安全方法.

更新:

public synchronized void increment() {
    c++;
}
Run Code Online (Sandbox Code Playgroud)

要么

AtomicInteger integer = new AtomicInteger(1);
//somewhere else in code
integer.incrementAndGet();
Run Code Online (Sandbox Code Playgroud)

另请阅读:Java中是否有iinc原子?


Evg*_*eev 6

不是它不会,它可能会导致真正的问题.该测试应该打印200000000,但它不会因线程干扰

static int n;

public static void main(String[] args) throws InterruptedException {
    Runnable r = new Runnable() {
        public void run() {
            for(int i = 0; i < 100000000; i++) {
                n++;
            }
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(n);
}
Run Code Online (Sandbox Code Playgroud)

注意,volatile并没有解决问题.

  • 实际上,这段代码甚至没有使用 `IINC` 指令来增加 `n` 字段。`IINC` 仅用于局部变量,在这种情况下仅用于 `i++`。 (2认同)

Cla*_*oft 6

{虽然已经有一个公认的答案,但我想澄清一些事情,因此这是迟到的,技术上不必要的答案}

您的问题的答案取决于您IINC是指++操作员的指示,还是其他答案.

使用++一个静态或实例字段无非是获取,增量,并设置多,因此它是不是原子(其他的答案更详细地解释这一点).

既然你问这个IINC 指令是否是原子的,那么这不是真正的答案.事实上,没有回答这个问题的解决说明,所有的人似乎是根据各地运营商的实例或静态字段中使用.


IINC指令仅对局部变量进行操作.顾名思义,它们只是本地的,只能从非常有限的范围内访问.因此,无法从另一个Thread访问局部变量.这意味着指令是否是原子的并不重要.