java – AtomicReference和Synchronized之间的区别是什么?

前端之家收集整理的这篇文章主要介绍了java – AtomicReference和Synchronized之间的区别是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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;}
}

按优先顺序降序排列:

>尽可能选择不变性.>对于不可变的代码,尝试将变异限制在一个线程中.>如果只需要在线程之间进行一项更改,请使用原子方法.>如果跨线程的多个更改需要在不受其他线程干扰的情况下发生,请使用锁定.

猜你在找的Java相关文章