假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是()

发布时间 2023-09-22 19:07:17作者: xiuer211

假设 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。
一共有以下几种情况(可能不全):
蓝色框代表不会保存结果,因为黄色框数字将蓝色框数字覆盖了
image
原题链接: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。换句话说,递增操作的结果丢失了。这是一个争用条件。