mar*_*ary 2 multithreading preemption
我有以下面试问题:
class someClass
{
int sum=0;
public void foo()
{
for(int i=0; i<100; i++)
{
sum++
}
}
}
Run Code Online (Sandbox Code Playgroud)
有两个并行线程在foo方法中运行.最后总和的价值从100到200不等.问题是为什么.据我所知,只有一个线程获得一个CPU,并且线程在运行时被抢占.在什么时候干扰会导致总和达不到200?
Mar*_*tos 10
增量不是原子的.它读取值,然后写出递增的值.在这两个操作之间,另一个线程可以以复杂的方式与总和进行交互.
值的范围实际上不是100到200.该范围基于线程轮流或同时执行每个读取的错误假设.还有更多可能的交错,其中一些产生明显不同的值.最坏的情况如下(x
表示表达式中使用的隐式临时sum++
):
Thread A Thread B
---------------- ----------------
x ? sum (0)
x ? sum (0)
x + 1 ? sum (1)
x ? sum (1)
x + 1 ? sum (2)
?
x ? sum (98)
x + 1 ? sum (99)
x + 1 ? sum (1)
x ? sum (1)
x ? sum (1)
x + 1 ? sum (2)
?
x ? sum (99)
x + 1 ? sum (100)
x + 1 ? sum (2)
Run Code Online (Sandbox Code Playgroud)
因此,最低可能值为2.简单来说,两个线程撤消对方的辛勤工作.你不能低于2,因为线程B不能向线程A提供零 - 它只能输出递增的值 - 并且线程A必须依次递增线程B给它的1.