Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iinc在Java中是原子的吗? 我知道在没有锁的情况下,C++中的增量运算不是原子的。_Java_Jvm_Atomic_Atomicity - Fatal编程技术网

iinc在Java中是原子的吗? 我知道在没有锁的情况下,C++中的增量运算不是原子的。

iinc在Java中是原子的吗? 我知道在没有锁的情况下,C++中的增量运算不是原子的。,java,jvm,atomic,atomicity,Java,Jvm,Atomic,Atomicity,JVM会在其iinc指令的实现上添加任何锁吗?否 检索c的当前值 将检索到的值增加1 将递增的值存储回c 您需要使用synchronized关键字或使用AtomicXXX方法来实现线程安全 更新: public synchronized void increment() { c++; } 或 另请阅读:不,它不是原子的,字节码可以与其他线程交错 不是,它不是,它会引起真正的问题。这个测试应该打印20000000,但由于线程干扰,它没有打印 static int n; publi

JVM会在其
iinc
指令的实现上添加任何锁吗?

  • 检索c的当前值
  • 将检索到的值增加1
  • 将递增的值存储回c

您需要使用
synchronized
关键字或使用
AtomicXXX
方法来实现线程安全

更新

public synchronized void increment() {
    c++;
}


另请阅读:

不,它不是原子的,字节码可以与其他线程交错

不是,它不是,它会引起真正的问题。这个测试应该打印20000000,但由于线程干扰,它没有打印

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);
}
static int n;
公共静态void main(字符串[]args)引发InterruptedException{
Runnable r=新的Runnable(){
公开募捐{
对于(int i=0;i<100000000;i++){
n++;
}
}
};
螺纹t1=新螺纹(r);
螺纹t2=新螺纹(r);
t1.start();
t2.start();
t1.join();
t2.连接();
系统输出println(n);
}

请注意,
volatile
不能解决问题。

i++在java中不是原子的。
最好使用

AtomicInteger atomic= new AtomicInteger(1);
有这样定义的方法

atomic.getAndDecrement();
atomic.getAndIncrement();
atomic.decrementAndGet();
atomic.incrementAndGet();
使用上述方法的任何操作都是原子操作

此类位于
java.util.concurrent.atomic
包之下。
Java
1.5
为线程安全性和线程并发性添加了许多功能。

它不是原子的。以下是静态int的后期增量生成的字节码:

0 getstatic 18;    // Load value of variable.
3 iconst_1;
4 iadd;
5 putstatic 18;    // Store value.

您的问题的答案取决于您指的是
IINC
指令还是
++
运算符(其他答案所指)

在静态或实例字段上使用
++
只不过是get、increment和set,因此它不是原子的(其他答案对此进行了更详细的解释)

但是

因为您询问了
IINC
指令是否是原子指令,所以这不是真正的答案。事实上,这个问题的答案中没有一个是针对指令的,所有这些答案似乎都是基于实例或静态字段上使用的运算符



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

您应该阅读Java的并发文档,这对于理解Java并发的基本概念非常有帮助。+1是很好的参考资料。要说迂腐,我相信
integer.getAndIncrement()
等同于
I++
(而不是
incrementAndGet()
)!这不是正确的答案<代码>i++编译为
iinc
用于局部变量,其中并发性不受关注。如果
i
是一个字段,那么它将被编译为@Ellen Spertus的答案,需要进行适当的同步。关于这个主题,这个问题有一个很好的答案:@EfeKahraman那么这是否意味着Java字节码指令
iinc
是线程安全的?不管怎样,我找到了一个答案:实际上,这段代码甚至没有使用
iinc
指令来增加
n
字段
IINC
仅用于局部变量,在本例中仅用于
i++
。感谢您的回答!澄清得很好!从我的答案中也添加了链接到你的答案。
0 getstatic 18;    // Load value of variable.
3 iconst_1;
4 iadd;
5 putstatic 18;    // Store value.