此HardwareData类模拟并发编程中的get-and-set和swap指令。我使用synchronized语句来确保在执行getAndSet或Swap时没有其他get / set / swap / getandset正在发生?你们认为这是线程圣人吗?
public class HardwareData {
private boolean value = false;
public HardwareData(boolean value){
this.value = value;
}
public synchronized boolean get(){
return value;
}
public synchronized void set(boolean newValue){
value = newValue;
}
public boolean getAndSet(boolean newValue){
synchronized(this) {
boolean oldValue = this.get();
this.set(newValue);
return oldValue;
}
}
public void swap(HardwareData other){
synchronized(this){
boolean temp = this.get();
this.set(other.get());
other.set(temp);
}
}
答案 0 :(得分:1)
绝对不是。 swap
方法不是线程安全的,因为在以下期间您不会保留other
对象的互斥锁:
this.set(other.get());
other.set(temp);
意味着当您处于这两行之间时,第三个线程可能会调用other.set(boolean)
,从而更改other
的内部状态。如果同时发生两次object1.swap(object2)
和object2.swap(object1)
的调用,也会有陷入僵局的风险。
要解决此问题,swap
方法必须同时对两个对象进行同步,这很棘手,因为它可能会导致死锁,具体取决于它们获取的顺序。
另外:在方法声明中添加synchronize
与在synchronized(this){ ... }
中包装整个方法主体相同。