java - 这些方法是线程安全的吗?

标签 java multithreading synchronization

该 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/

相关文章:

java - 查找字符串的所有子字符串 - StringIndexOutOfBoundsException

c++ - vector 引用operator []线程安全写吗?

c# - 如何制作一个c#线程安全的随机数生成器

C#:关于成员变量线程安全的问题

java - Double check 中不稳定的东西是什么?

java - 尝试使用 setImageResource 时应用程序崩溃

c# - 匿名事件

java - 在 TestNg 框架执行 Citrus 测试用例时无法获取 citrus TestContext 对象

c - C 多线程程序中的错误

android-studio - 无法解析 '...' : Could not resolve project :react-native-navigation 的依赖关系