java - 使该类线程安全

标签 java multithreading thread-safety

我正在准备考试,我有以下来自上一个考试问题的非线程安全代码:

class Q3 {
    private boolean f[] = new boolean[20];

    public Q3() { 
        for (int j = 0; j < 20; j++) {
            f[j] = true;
        }
    }

    public void negate(int a, int b) {
        for(int j = a; j < b; j++) {
            f[j] = !f[j];
        }
    }

    public void swap(int a, int b) {
        boolean temp = f[a];
        f[a] = f[b];
        f[b] = temp;
    }
}

我通过进行以下调整使其线程安全:

class Q3 {
    private boolean f[] = new boolean[20];

    public Q3() {
        for (int j = 0; j < 20; j++) {
            f[j] = true;
        }
    }

    synchronized void negate(int a, int b) {
        for (int j = a; j < b; j++) {
            f[j] = !f[j];
        }
    }

    synchronized void swap(int a, int b) {
        boolean temp = f[a];
        f[a] = f[b];
        f[b] = temp;
    }
}

但是有人可以向我解释为什么原始代码不是线程安全的吗?我知道如何使代码线程安全,但我仍然不确定为什么代码被定义为线程安全

最佳答案

此答案假设多个线程可能作用于 Q3 对象的同一实例。以swap()方法为例:

public void swap(int a, int b) {
    boolean temp = f[a];
    f[a] = f[b];
    f[b] = temp;
}

如果两个单独的线程都调用 swap() 并交错,则可能会发生以下情况:

Thread one:
boolean temp = f[a];
f[a] = f[b];

Thread two:
boolean temp = f[a];   // his temp = f[b], wrong!

Thread one:
f[b] = temp;           // f[b] = f[b], no swap!

Thread two:
f[a] = f[b];
f[b] = temp;           // f[a] = f[b], wrong

最终结果是 f[a]f[b] 最终都是后者的值,对于两者 线程,这显然不是你想要的。通过使 swap() 方法同步,您可以确保给定线程将原子执行该方法,即给定线程将完成单独使用整个方法,或者不会,中间没有任何内容。

关于java - 使该类线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41424501/

相关文章:

Swift Realm 将预取对象保存到新对象中

c# - 在 .NET 中使用 Thread.Abort() 和处理 ThreadAbortException 是否安全?

Java hashmap 只读线程安全

java - 自动更新 map /集并检查大小

c - 使用信号量实现并发的线程二叉树

java - 如何使用 Bot Framework SDK for Java 将卡片添加到 Microsoft 团队机器人?

c# - C++ 右值引用和移动语义

java - Android - 将多个 ASyncTaskLoader 类作为 InnerClasses 放入 "manager"类中

java - JTabpan 拆分按钮

java - 并发和多线程有什么区别?