基本的多线程

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.