且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

同步对易失性字段的写访问(廉价读写块)

更新时间:2022-11-24 22:49:41

Volatile提供对没有同步的字段的快速线程安全无锁访问

Volatile provides fast thread-safe lock-free access to a field without synchronization

private volatile String foo;

public String getFoo() {
    return foo;
}
public void setFoo(String in) {
    this.foo = in;
}

volatile解决3个问题1)内存可见性2)原子写入为double和long字段3)禁止指令重新排序。但是,如果您需要在一个字段上进行多次操作作为一个原子事务(例如增量),这还不够。此代码已损坏

volatile solves 3 problems 1) memory visibility 2) atomic writes for double and long fields 3) forbids instructions reordering. But it's not enough if you need several operations over a field as one atomic transaction, such as increment. This code is broken

private volatile int id;

public void incrementId() {
     id++;
}

因为如果2个线程同时读取并递增并保存结果,那么结果第一个增量的值将被第二个增量的结果覆盖。为了防止这种情况发生,我们需要使用同步

because if 2 threads simulataneously read and increment it and save the result then the result of the first increment will be overwritten with the result of the second increment. To prevent this from happening we need to use synchronization

 private int id;

 public synchronized int nextId() {
       return ++id;
 }

或java.util.concurrent.atomic package

or java.util.concurrent.atomic package

 private AtomicInteger id = new AtomicInteger();

 public void incrementId() {
     return id.incrementAndGet();
 }