首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java并发编程中,是否需要在读取值时使用同步?

在java并发编程中,是否需要在读取值时使用同步?
EN

Stack Overflow用户
提问于 2016-05-19 01:47:12
回答 2查看 221关注 0票数 4

这个类可以用于多线程,因为它是线程安全的.

代码语言:javascript
复制
public class Hello {
    private int value = 0;

    public synchronized int get() {
        return value;
    }

    public synchronized void set(int value) {
        this.value = value;
    }
}

我知道,除了set()之外,当get()时,我们必须使用同步的原因是内存可见性。

而java易失性关键字可以用于内存可见性。

那么..。这个类也是线程安全的??

代码语言:javascript
复制
public class Hello {
    private volatile int value = 0;

    public int get() {
        return value;
    }

    public synchronized void set(int value) {
        this.value = value;
    }
}
EN

回答 2

Stack Overflow用户

发布于 2016-05-19 02:24:37

在您的示例中,不需要在get()set方法中使用value,因为value属性是用volatile关键字声明的。

这是因为volatile关键字强制在写入线程和读取器线程之间的关系发生之前。

Java语言规范,8.3.1.4节。易挥发场

Java编程语言允许线程访问共享变量(§17.1)。作为一项规则,为了确保一致和可靠地更新共享变量,线程应该通过获取一个锁来确保它独占使用这些变量,该锁通常对这些共享变量强制互斥。 Java编程语言提供了第二种机制,即易失性字段,这比出于某些目的进行锁定更方便。 字段可以声明为可变值,在这种情况下,Java内存模型确保所有线程都看到变量的一致值(§17.4)。

因此,在您的示例中,不需要同步get()set()方法。

票数 1
EN

Stack Overflow用户

发布于 2016-07-07 09:15:54

在您的类Hello中,只有一个字段int value。同步锁定整个对象,从而进行大量操作,而可以使用AtomicInteger。因为原子*变量更快。易失性只是满足“发生前”,你不能达到原子性的操作,如“检查,然后行动”与挥发分。

要使Hello类线程安全,最好的方法是

代码语言:javascript
复制
import java.util.concurrent.atomic.AtomicInteger;

public class Hello {
    private AtomicInteger value;

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

    public synchronized void set(int value) {
        this.value.set(value);
    }
}

正如这个职位中提到的

如果某个对象只有一个字段,或者它的关键更新仅限于对象的一个字段,则不使用同步或其他线程安全集合、原子变量(AtlomicInteger、AtomicReference等)。可以利用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37312655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档