您如何确保多个线程可以安全地访问类字段?

Chr*_*ers 10 java multithreading synchronized

当多个线程通过getter方法访问类字段时,如何保持线程安全?synchronized关键字是否足够?

这样安全吗:

public class SomeClass {
    private int val;

    public synchronized int getVal() {
        return val;
    }

    private void setVal(int val) {
        this.val = val;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,二传手会引入更多并发症吗?

Cow*_*wan 17

如果你也在setter上使用'synchronized',那么这段代码就是线程安全的.但是它可能不够细小; 如果你有20个getter和setter并且它们都是同步的,你可能会创建一个同步瓶颈.

在这个特定的实例中,使用单个int变量,然后消除'synchronized'并标记int字段'volatile'也将确保可见性(每个线程在调用getter时将看到'val'的最新值)但它可能不会同步足以满足您的需求.例如,期待

 int old = someThing.getVal();
 if (old == 1) {
    someThing.setVal(2);
 }
Run Code Online (Sandbox Code Playgroud)

当且仅当它已经为1时,将val设置为2是不正确的.为此,您需要一个外部锁或一些原子比较和设置方法.

我强烈建议你阅读Brian Goetz 等人的Java Concurrency In Practice,它对Java的并发结构有最好的报道.