Documentation

The Java™ Tutorials
Hide TOC
Atomic Variables原子变量
Trail: Essential Java Classes
Lesson: Concurrency
Section: High Level Concurrency Objects

Atomic Variables原子变量

The java.util.concurrent.atomic package defines classes that support atomic operations on single variables. java.util.concurrent.atomic包定义了支持单变量原子操作的类。All classes have get and set methods that work like reads and writes on volatile variables. 所有类都有getset方法,它们的工作方式类似于对volatile变量的读取和写入。That is, a set has a happens-before relationship with any subsequent get on the same variable. 也就是说,set与同一变量上的任何后续get具有“发生在之前”关系。The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.原子compareAndSet方法也具有这些内存一致性特性,适用于整数原子变量的简单原子算术方法也具有这些特性。

To see how this package might be used, let's return to the Counter class we originally used to demonstrate thread interference:要了解如何使用此包,让我们回到最初用于演示线程干扰的Counter类:

class Counter {
    private int c = 0;

    public void increment() {
        c++;
    }

    public void decrement() {
        c--;
    }

    public int value() {
        return c;
    }

}

One way to make Counter safe from thread interference is to make its methods synchronized, as in SynchronizedCounter:使Counter免受线程干扰的一种方法是使其方法同步,如SynchronizedCounter

class SynchronizedCounter {
    private int c = 0;

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

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }

}

For this simple class, synchronization is an acceptable solution. 对于这个简单的类,同步是一个可接受的解决方案。But for a more complicated class, we might want to avoid the liveness impact of unnecessary synchronization. 但是对于一个更复杂的类,我们可能希望避免不必要的同步对活跃度的影响。Replacing the int field with an AtomicInteger allows us to prevent thread interference without resorting to synchronization, as in AtomicCounter:使用AtomicInteger替换int字段可以防止线程干扰,而无需借助同步,如AtomicCounter所示:

import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
    private AtomicInteger c = new AtomicInteger(0);

    public void increment() {
        c.incrementAndGet();
    }

    public void decrement() {
        c.decrementAndGet();
    }

    public int value() {
        return c.get();
    }

}

Previous page: Concurrent Collections
Next page: Concurrent Random Numbers