AtomicReference和Synchronized之间有什么区别? [英] Which is the difference between AtomicReference and Synchronized?

查看:350
本文介绍了AtomicReference和Synchronized之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AtomicReference和Synchronized之间有什么区别吗?
例如

Is there any difference between AtomicReference and Synchronized?
E.G.

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

}

然后将类传递给尝试同时使用该类的某些线程,如果使用此命令,是否也是同一件事:

And I pass the class to some threads that try to use the class at the same time, is it the same thing if I use this:

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

然后在线程中使用synchronized来访问该类?

And then in the thread use synchronized before access to the class?

推荐答案

在第一个示例中,您没有初始化引用,它应该是:

You didn't initialize the reference in the first example, it should probably be:

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

访问限制所在的位置很重要.如果将控件放在要访问的对象中,则它可以仅控制其不变量,而脆弱性要比依赖线程来使所有对象正确同步要脆弱得多,在这种情况下,行为不佳的访问线程可能会破坏正在访问的对象.因此,第一个示例在该帐户上要好得多.

Where the access restriction is located is important. If you put the control within the object being accessed then it can have sole control of its invariants, which is much less fragile than relying on the threads to all synchronize properly, where one badly behaved accessing thread can corrupt the thing being accessed. So the first example is much better on that account.

如果更改第二个示例,以便对象可以控制其自身的锁定(因此它不依赖于线程安全地对其进行访问),例如:

If you change the second example so that the object has control over its own locking (so it is not relying on threads accessing it to do so safely), like this:

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以及处理负载,通常原子方法应该更快.同步方法是一种更通用的机制.使用同步块,您可以更轻松地将多个分配组合在一起,而使用原子引用,则涉及更多.

then it's a closer comparison, one relies on locking and the other on atomic references. The one using AtomicReference tries to avoid locking using machine-level atomic processing instructions. Which is faster may depend on your hardware and jvm and the processing load, typically the atomic approach should be faster. The synchronized approach is a more general purpose mechanism; with the synchronized block you can group together multiple assignments much more easily, where with atomic references it's much more involved.

就像James在他的回答中所说的,随着同步的进行,您的线程正在等待锁;没有超时,并且可能发生死锁.使用原子引用,线程无需等待共享锁即可进行更改.

As James says in his answer, with synchronization your threads are waiting for a lock; there is no timeout, and deadlock is possible. With the atomic reference the thread makes its change with no waiting on a shared lock.

实现此目的最简单,性能最佳的方法是组织代码,以便可以使对象不可变,从而避免所有锁定,繁忙等待和缓存更新:

The simplest and best-performing way to implement this would be to organize your code so that you can make the object immutable, so you would avoid all locking, busy-waiting, and cache updating:

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

按优先级降序排列:

  • 尽可能保持不变.
  • 对于不可更改的代码,请尝试将更改限制在线程内.
  • 如果只有一件事需要在线程之间进行更改,请使用原子方法.
  • 如果跨线程的多个更改需要一起发生而不受其他线程的干扰,请使用锁定.

这篇关于AtomicReference和Synchronized之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆