当前位置: 首页 > 面试题库 >

竞争条件:整数的最小和最大范围

锺离俊雄
2023-03-14
问题内容

最近在一次采访中有人问我这个问题。

给定以下代码,静态整数的最小和最大可能值是num多少?

import java.util.ArrayList;
import java.util.List;

public class ThreadTest {
    private static int num = 0;

    public static void foo() {
        for (int i = 0; i < 5; i++) {
            num++;
        }
    }

    public static void main(String[] args) throws Exception{
        List<Thread> threads = new ArrayList<Thread>();
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new Task());
            threads.add(thread);
            thread.start();
        }
        for (int i = 0; i < 5; i++) {
            threads.get(i).join();
        }
        // What will be the range of num ???
        System.out.println(ThreadTest.num);
    }
}

class Task implements Runnable {
    @Override
    public void run() {
        ThreadTest.foo();
    }

}

我告诉他们,最大值将为25(在没有竞争条件的情况下),而最小值将为5(在每次迭代时所有线程之间的竞争条件的情况下)。
但是面试官说,最小值甚至可以低于5。这
怎么可能?


问题答案:

我声称最小值可能是2。

这样做的关键是的非原子性num++,即它是读和写,它们之间可能有其他操作。

调用线程T1..T5:

  • T1读取0,T2读取0;
  • T1写入1,然后读取和写入3次。
  • 然后T2写1;
  • 然后,T1读取为1;
  • 然后T2-5完成所有工作
  • 然后,最后,T1写入2。

(注意:如果每个线程至少有2个,则结果2既不取决于线程数,也不取决于迭代数。)

对此的诚实回答是:确实没有关系。有一个数据竞赛,如JLS
17.4.5
定义

当程序包含两个冲突的访问时(第17.4.1节[“如果至少一个访问是写操作,则对同一变量的两次访问(读或写)被认为是冲突的。”])通过事前发生的关系,它据说包含一个
数据竞争

(线程中的动作之间没有 发生事前 关系)

因此,您无法有效地依靠它的作用。这只是不正确的代码。

(此外,我知道此问题的答案并不是因为一些来之不易的调试多线程代码或深入的技术阅读:之所以知道这一点,是因为我之前在其他地方都已经阅读过此答案。这是一个客厅技巧,仅此而已,所以
问最小值 不是一个很好的面试问题)。



 类似资料:
  • 9.1. 竞争条件 在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序,x是在y之前还是之后还是同时发生是没法

  • 问题内容: 我正在寻找python中整数的最小值和最大值。例如,在Java中,我们有和。python中是否有类似的东西? 问题答案: Python 3 在Python 3中,此问题不适用。普通int类型是无界的。 但是,你实际上可能正在寻找有关当前解释器的字长的信息,在大多数情况下,该信息将与机器的字长相同。该信息在Python 3中仍以形式提供,这是一个有符号的单词可以表示的最大值。等效地,它是

  • 我一直在寻找这个问题的答案,但运气不佳,所以希望有人能帮助我! 我正在处理周期性数据,我试图找到两个波峰和两个波谷的相关值——这不一定等同于最大/最小和第二个最大/最小值,而是最大/最小和第二个最大/最小值,条件是该值大于/小于前面和后面的值。 这是一个循环的例子 我有 1000 个周期,所以我在 dplyr 中使用group_by对周期进行分组,然后希望在组中应用条件最大值/最小值参数。 我很感

  • 9.6. 竞争条件检测 即使我们小心到不能再小心,但在并发程序中犯错还是太容易了。幸运的是,Go的runtime和工具链为我们装备了一个复杂但好用的动态分析工具,竞争检查器(the race detector)。 只要在go build,go run或者go test命令后面加上-race的flag,就会使编译器创建一个你的应用的“修改”版或者一个附带了能够记录所有运行期对共享变量访问工具的tes

  • 上面的输出是1。我不知道为什么。有人能解释一下吗? 提前谢谢。