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块,您可以更轻松地将多个分配组合在一起,其中使用原子引用更加复杂.
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;}
}
按优先顺序降序排列:
>尽可能选择不变性.>对于不可变的代码,尝试将变异限制在一个线程中.>如果只需要在线程之间进行一项更改,请使用原子方法.>如果跨线程的多个更改需要在不受其他线程干扰的情况下发生,请使用锁定.