gpt4 book ai didi

java - AtomicReference 和 Synchronized 之间有什么区别?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:52:39 24 4
gpt4 key购买 nike

AtomicReference和Synchronized有区别吗?
例如

public class Internet {
AtomicReference<String> address;
public String getAddress(){
return address.toString();
}
public void setAddress(String address) {
this.address.set(address);
}

}

然后我将这个类传递给一些同时尝试使用这个类的线程,如果我使用这个是不是一样的:

public class Internet {
String address;
public String getAddress(){
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

然后在线程中使用synchronized访问类之前?

最佳答案

你没有在第一个例子中初始化引用,它可能应该是:

public class Internet {
AtomicReference<String> address = new AtomicReference<String>();
public String getAddress(){
String s = address.get();
return s == null ? null : s.toString();
}
public void setAddress(String address) {
this.address.set(address);
}
}

访问限制的位置很重要。如果将控件放在被访问的对象中,那么它可以单独控制其不变量,这比依赖线程正确同步要安全得多,在后者中,一个行为不当的访问线程可能会破坏被访问的对象。所以第一个例子在那个方面要好得多。

如果您更改第二个示例,以便对象可以控制自己的锁定(因此它不依赖于访问它的线程来安全地执行此操作),如下所示:

public class Internet {
private final Object lock = new Object();
private String s;
public String getAddress() {
synchronized(lock) {
return s;
}
}
public void setAddress(String s) {
synchronized(lock) {
this.s = s;
}
}
}

然后是更接近的比较,一个依赖于锁定,另一个依赖于原子引用。使用 AtomicReference 的方法试图避免使用机器级原子处理指令进行锁定。哪个更快可能取决于您的硬件和 jvm 以及处理负载,通常原子方法应该更快。同步方法是一种更通用的机制;使用同步块(synchronized block),您可以更轻松地将多个分配组合在一起,而使用原子引用则涉及更多。

As James says in his answer ,通过同步,您的线程正在等待锁定;没有超时,死锁是可能的。使用原子引用,线程无需等待共享锁即可进行更改。

实现这一点的最简单且性能最好的方法是组织代码,使对象不可变,从而避免所有锁定、忙等待和缓存更新:

public final class Internet {
private final String s;
public Internet(String s) {
this.s = s;
}
public String getAddress() {return s;}
}

按偏好降序排列:

  • 尽可能选择不变性。
  • 对于不能不可变的代码,尽量将变更限制在一个线程内。
  • 如果只有一件事必须跨线程更改,请使用原子方法。
  • 如果跨线程的多个更改需要一起发生而不受其他线程的干扰,请使用锁定。

关于java - AtomicReference 和 Synchronized 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28834489/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com