同步对易失性字段的写访问(廉价读写块) [英] Synchronize write access to Volatile field (Cheap read-write block)

查看:146
本文介绍了同步对易失性字段的写访问(廉价读写块)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下课程将被大量阅读,但只是偶尔写的。它将用于多线程Web应用程序,因此它需要是线程安全的:

Let's say I have the following class that will be read heavily, but only written to occasionally. It will be used in a multi-threaded web app, so it needs to be thread safe:

public class Foo {
    private volatile String foo;
    public String getFoo() {
        return foo;
    }
    public synchronized String setFoo(String in) {
        this.foo = in;
    }
}

Java并发(http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html )声明这是一种保护写访问的脆弱方法,同时改善了读访问。什么是这种模式的更强的替代品?或者,如果foo在读取繁重的环境中需要变量,还是其他任何选择?谢谢。

Java Concurrency (http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html) states that this is a fragile way to protect write access while improving read access. What is a stronger alternative to this pattern? Or any alternative if foo will need to mutable in a read-heavy environment? Thank you.

推荐答案

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();
 }

这篇关于同步对易失性字段的写访问(廉价读写块)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆