假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是()
假设 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。换句话说,递增操作的结果丢失了。这是一个争用条件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix