易失性是线程安全的,那么AtomicInteger需要什么

时间:2014-04-10 09:23:38

标签: java multithreading atomic volatile

就像AtomicInteger是线程安全的,因为我已经完成了它使用的代码和技术,根据理论说它是一个线程安全的

在计算机科学中,比较和交换(CAS)是多线程中用于实现同步的原子指令。 它将内存位置的内容与给定值进行比较,并且只有它们相同时,才将该内存位置的内容修改为给定的新值。  这是作为单个原子操作完成的。原子性保证了新值是根据最新信息计算出来的;如果值已更新 在此期间,通过另一个线程,写入将失败。操作的结果必须表明它是否进行了替换;这可以做到 使用简单的布尔响应(此变体通常称为比较和设置),或者返回从内存位置读取的值(而不是写入它的值)。

我见过AtomicInteger类的代码

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

我有一个问题,如果我做一个变量一个线程安全,只需将它声明为volatile。因此 读取该变量的所有线程都将获得最新值。 任何人都可以解释一下,当我们有VOLATILE关键字来使变量线程安全时 那么为什么我们有AtomicInteger类来使变量线程安全。与基于AtomicInteger的volatile关键字的优点是什么。

如果我们声明volatile volatile和volatile double它们是线程安全的,如果不是 那么为什么他们不是线程安全的。和没有volatile的int是线程安全的。请expalin

3 个答案:

答案 0 :(得分:5)

你错过了AtomicInteger中非常重要的部分:

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

你无法使用简单的volatile模仿纯java中的 。它调用本机代码来执行实际的原子比较和设置(CAS)操作

如果您有一个线程更新字段和读取字段的任意数量的线程,则易失性。要从多个线程安全更新字段,您需要原子同步。

答案 1 :(得分:1)

一个volatile int被保存为可以同时读取 - 但不是read + write,就像atomicInteger类的原子incrementAndGet方法一样。

如果在比较"最后一个好的值"之后int更改了,那么你的比较和交换将无法同步并执行实际写入

答案 2 :(得分:-1)

使用VOLATILE不会使您的变量成为线程安全的,它告诉编译器变量可能随时更改,而不一定是由提供的代码更改。