如何在Java中同步或锁定变量?

2022-08-31 12:47:20

让我使用这个小而简单的示例:

class Sample {
    private String msg = null;

    public void newmsg(String x){
        msg = x;
    }

    public String getmsg(){
        String temp = msg;
        msg = null;
        return temp;
    }
}

假设该函数由我无法访问的其他线程调用。newmsg()

我想使用 synchonize 方法来保证字符串每次只由一个函数使用。换句话说,函数不能与 同时运行。msgnewmsg()getmsg()


答案 1

这很简单:

class Sample {
    private String message = null;
    private final Object lock = new Object();

    public void newMessage(String x) {
        synchronized (lock) {
            message = x;
        }
    }

    public String getMessage() {
        synchronized (lock) {
            String temp = message;
            message = null;
            return temp;
        }
    }
}

请注意,我既没有使方法本身同步,也没有在 上同步。我坚信,最好只在只有您的代码有权访问的对象上获取锁,除非您故意公开锁。它使自己更容易向自己保证,没有其他任何东西会以与代码不同的顺序获取锁,等等。this


答案 2

对于此功能,您最好根本不使用锁。尝试原子引用。

public class Sample {
    private final AtomicReference<String> msg = new AtomicReference<String>();

    public void setMsg(String x) {
        msg.set(x);
    }

    public String getMsg() {
        return msg.getAndSet(null);
    }
}

无需锁,恕我直言,代码更简单。在任何情况下,它都使用标准构造来执行所需的操作。


推荐