该 HardwareData 类模拟并发编程中获取和设置以及交换指令的思想。我使用同步语句来确保在执行 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);
}
}
最佳答案
绝对不是。 swap
方法不是线程安全的,因为在以下期间您没有持有 other
对象的互斥锁:
this.set(other.get());
other.set(temp);
这意味着当您位于这两行之间时,第三个线程可能能够调用 other.set(boolean)
,从而更改 other
的内部状态。如果同时发生对 object1.swap(object2)
和 object2.swap(object1)
的两次调用,还存在陷入死锁的风险。
要解决此问题,swap
方法必须同时在两个对象上同步,这很棘手,因为它可能会导致死锁,具体取决于它们获取的顺序。
此外:将 synchronize
添加到方法声明中与将整个方法主体包装在 synchronized(this){ ... }
中相同。
关于java - 这些方法是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39843075/