Win*_*ter 67 java synchronization
让我用这个小而简单的样本:
class Sample {
private String msg = null;
public void newmsg(String x){
msg = x;
}
public String getmsg(){
String temp = msg;
msg = null;
return temp;
}
}
Run Code Online (Sandbox Code Playgroud)
我们假设该函数newmsg()由我无权访问的其他线程调用.
我想使用synchonize方法来保证字符串msg每次只被一个函数使用.换句话说,功能newmsg()不能同时运行getmsg().
Jon*_*eet 155
这很简单:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我没有使方法本身同步或同步this.我坚信只有你的代码可以访问的对象才能获得锁,这是个好主意,除非你故意暴露锁.这样可以更容易地让自己放心,没有其他任何东西会以与代码不同的顺序获取锁定等.
Pet*_*rey 49
对于此功能,最好不要使用锁.尝试AtomicReference.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
不需要锁,代码更简单恕我直言.在任何情况下,它都使用标准结构,它可以满足您的需求.
小智 9
从Java 1.5开始,考虑java.util.concurrent包总是一个好主意.它们现在是java中最先进的锁定机制.同步机制比java.util.concurrent类更重要.
该示例看起来像这样:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Sample {
private final Lock lock = new ReentrantLock();
private String message = null;
public void newmsg(String msg) {
lock.lock();
try {
message = msg;
} finally {
lock.unlock();
}
}
public String getmsg() {
lock.lock();
try {
String temp = message;
message = null;
return temp;
} finally {
lock.unlock();
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用synchronized关键字。
class sample {
private String msg=null;
public synchronized void newmsg(String x){
msg=x;
}
public synchronized string getmsg(){
String temp=msg;
msg=null;
return msg;
}
}
Run Code Online (Sandbox Code Playgroud)
在方法上使用synchronized关键字将要求线程获取 实例的锁sample。因此,如果任何一个线程在 中newmsg(),则任何其他线程都无法获得 实例上的锁sample,即使它试图调用getmsg()。
另一方面,synchronized如果您的方法执行长时间运行的操作,则使用方法可能会成为瓶颈 - 所有线程,即使它们想要调用该对象中可以交错的其他方法,仍然必须等待。
IMO,在您的简单示例中,可以使用同步方法,因为您实际上有两个不应该交错的方法。然而,在不同的情况下,有一个锁对象来同步可能更有意义,如 Joh Skeet 的回答所示。