除 "synchronized" 之外的 Java 类中的 getter 的线程安全习惯用法


public class ThreadSafe {
    private int aField;
    public synchronized void setAField(int value) {
        aField = value;
    }
    public synchronized int getAField() {
        return aField;
    }
}
public class ThreadSafeToo {
    private volatile int aField;
    public synchronized void setAField(int value) {
        aField = value;
    }
    public int getAField() {
        return aField;
    }
}
public class DontKnowIfThreadSafeButMostLikelyYes {
    private static int aField;
    public synchronized void setAField(int value) {
        aField = value;
    }
    public int getAField() {
        return aField;
    }
}

问题:

  • DontKnowIfThreadSafe但最有可能是线程安全吗?

  • 首选成语是什么,为什么?

ThreadSafeToo不需要

同步方法:易失性赋值是原子的,并提供可见性保证。

DontKnowIfThreadSafeButMostLikelyYes不是线程安全的:您需要将读取和写入同步到共享变量。

首选习语是主观的,但在您的情况下,有效的方法是:

public class ThreadSafeToo {
    private volatile int aField;
    public void setAField(int value) { aField = value; }
    public int getAField() { return aField; }
}

您的类DontKnowIfThreadSafeButMostLikelyYes不是线程安全的,因为static变量与同步点的实例变量没有区别。除此之外,结果将与其他情况不同。

第二个问题也是基于意见的。

我所知,DontKnowIfThreadSafeButMostPossibleYes不是线程安全的,因为2个线程可以同时设置和获取aField->问题

是否放置静态没有区别。两者都不是线程安全的。

我认为没有真正偏爱的偶像。在这种情况下,我会选择第一种方式。但是您也可以使用第二个,也可以使用锁。

Is DontKnowIfThreadSafeButMostLikelyYes thread-safe?

不,因为当getter和setter被调用时,getter可能会返回旧值。

What would be the preferred idiom and why?

在这种情况下,第二个类正确同步并且是线程安全的

最新更新