当通过多个线程通过getter方法访问类字段时,您如何维护线程安全性?同步关键字是否足够?
这是安全的吗?
public class SomeClass { private int val; public synchronized int getVal() { return val; } private void setVal(int val) { this.val = val; } }
或者是否引入更多的并发症?
解决方法
如果在这里也在setter上使用’synchronized’,这个代码是线程安全的.然而,它可能不够粒度;如果您有20个getter和setter,并且它们都已同步,则可能会创建同步瓶颈.
在这个具体的例子中,使用一个单一的int变量,然后消除’synchronized’并标记int字段’volatile’也将确保可见性(每个线程在调用getter时都会看到最新的’val’值),但它可能不会根据您的需要进行同步化.例如,期待
int old = someThing.getVal(); if (old == 1) { someThing.setVal(2); }
将val设置为2,如果且仅当它已经是1是不正确的.为此,您需要一个外部锁定或一些原子比较和设置方法.
我强烈建议您阅读Brian Goetz等人的Java并发实践,它具有Java并发结构的最佳覆盖.