我正在准备考试,我有以下来自上一个考试问题的非线程安全代码:
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/