我必须将线程之间的访问同步到一个共享对象,该对象的状态由几个字段组成。说:
class Shared{
String a; Integer b;
//constructor, getters and setters
....
}
我可能有很多线程在读取这个对象,做
//readers
shared.getA();
shared.getB();
并且只有一个线程会在某个时间点写入:
//writer
shared.setA("state");
shared.setB(1);
现在我的问题是如何确保读取线程不会发现处于不一致状态的共享对象。
我读了很多答案,说线程之间的一致性volatile
是解决方案,但我不确定它如何在多个字段上工作。例如,这就够了吗?
volatile String a; volatile Integer b;
另一种解决方案是使共享对象不可变并使用 AtomicReference,例如,
AtomicReference<Shared> shared = ....
然后作者将交换参考:
Shared prev = shared.get();
Shared newValue = new Shared("state",1);
while (!shared.compareAndSet(prev, newValue))
这种方法正确吗?谢谢!
更新在我的设置中,共享对象是从 a 中检索的ConcurrentHashMap<Id,Shared>
,因此评论一致认为,要走的路要么使用不可变方法,要么通过将 shared 上的更新同步在一起。但是,为了完整起见,很高兴知道上面的解决方案ConcurrentHashMap<Id,AtomicReference<Shared>>
是可行的还是错误的或者只是多余的。谁能解释一下?谢谢!