假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是()
boolean isOdd = false;
for(int i=1;i<=2;++i){
if(i%2==1)isOdd = true;
else isOdd = false;
a+=i*(isOdd?1:-1);
}
A:-1
B:-2
C:0
D:1
答案是D。
解释:
两个线程都有+1 ,-2的操作,但是关键是在保存a的值上,ThreadA对a+1,ThreadB也对a+1,ThreadB保存结果,此时a结果为1。虽然ThreadA对a+1但是并没有保存a,所以ThreadA保存a的值为1。
可以注意到虽然两个线程都进行了+1的操作,但是结果是错的。正是因为ThreadA将ThreadB的结果给覆盖了,而不是不执行+1。
知道这个道理之后就好办了
ThreadA的+1和-2操作都可以覆盖ThreadB的+1,-2。
一共有以下几种情况(可能不全):
蓝色框代表不会保存结果,因为黄色框数字将蓝色框数字覆盖了
原题链接:https://www.nowcoder.com/questionTerminal/2be86af464c04b9c9d7895d62dd46732?toCommentId=17308211
来源:牛客网
如果不理解多线程如何覆盖的可以看下面的解释:
下面是文章 https://zhuanlan.zhihu.com/p/639751407 来解释多线程如何覆盖
下表展示了递增线程再递减线程开始之前结束的结果,假设初值是1。
线程1(递增) | 线程2(递减 |
---|---|
加载值(值=1) | |
递增值(值=2) | |
存储值(值=2) | |
加载值(值=2) | |
递减值(值=1) | |
存储值(值=1) |
存储在内存中的最终值是1。当递减线程在递增线程开始之前完成时,最终值也是1,如下表所示:
线程1(递增) | 线程2(递减 |
---|---|
加载值(值=1) | |
递减值(值=0) | |
存储值(值=0) | |
加载值(值=0) | |
递增值(值=1) | |
存储值(值=1) |
然而,当指令交错执行时,结果是不同的,如下表所示:
线程1(递增) | 线程2(递减 |
---|---|
加载值(值=1) | |
递增值(值=2) | |
加载值(值=1) | |
递减值(值=0) | |
存储值(值=2) | |
存储值(值=0) |
这种情况下,最终结果是0。换句话说,递增操作的结果丢失了。这是一个争用条件。
标签:全局变量,ThreadA,结果,递增,初始值,线程,递减,加载 From: https://www.cnblogs.com/xiuer211/p/17723185.html