作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为考试复习,我有以下来自上一个考试问题的非线程安全代码:
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/
我是一名优秀的程序员,十分优秀!