java - 多个字段 : volatile or AtomicReference?

标签 java multithreading concurrency atomic atomicreference

我必须同步线程之间对共享对象的访问,该共享对象的状态由多个字段组成。说:

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)) 

这种方法正确吗?谢谢!

更新 在我的设置中,共享对象是从 ConcurrentHashMap<Id,Shared> 中检索的,所以评论一致认为要走的路要么使用不可变方法,要么通过同步所有共享的更新。但是,为了完整起见,很高兴知道上面的解决方案是否带有 ConcurrentHashMap<Id,AtomicReference<Shared>>是可行的或错误的或只是多余的。谁能解释一下?谢谢!

最佳答案

首先你应该使 Shared 不可变:

class Shared{
   private final String a; 
   private final int b;
   //constructor, getters and NO setters
}

如果您只有一个编写器,您可以安全地使用 volatile,在 AtomicReference 中则没有必要。在更新信息时,不应修改旧对象,而应创建新对象并将其分配给 volatile 引用。

关于java - 多个字段 : volatile or AtomicReference?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21283293/

相关文章:

java - 覆盖比较器接口(interface)的比较方法时使用什么排序算法?

c# - 如果操作首先完成,则使用 RegisterWaitForSingleObject

python 线程并行运行?

java - 如何在 android 或 : what exactly are daemon threads in android? 中安排一些代码执行

java - 如何配置注释来映射 servlet?

java - 所选的 App Engine SDK 无效

java - 两个线程,同一个静态变量,同一个值,并发访问

c++ - boost::asio::io_service 的 concurrency_hint 是什么意思?

c++ - thread_specific_ptr 多线程混淆

java - ConcurrentHashMap 的实际用例