这些方法是否安全?

时间:2016-10-04 01:56:54

标签: java multithreading synchronization

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

}

1 个答案:

答案 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){ ... }中包装整个方法主体相同。