竞争条件:整数的最小和最大范围 [英] Race condition: Min and Max range of an integer
问题描述
最近在一次采访中有人问我这个问题.
I was recently asked this question in an interview.
给出以下代码,静态整数num
的最小和最大可能值是多少?
Given the following code, what will be the min and max possible value of the static integer 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.
那怎么可能?
I told them that the max value would be 25 (in case there is no race condition), and min would be 5 (in case of a race condition between all the threads at every iteration).
But the interviewer said the the min value can go even below 5.
How is that possible?
推荐答案
我声称可能的最小值是2.
I claim the minimum value possible is 2.
此操作的关键是num++
的非原子性,即它是读和写,它们之间可能有其他操作.
The key to this is the non-atomicity of num++
, i.e., it is a read and a write, which may have other operations in between.
调用线程T1..T5:
Call the threads T1..T5:
- T1读取0,T2读取0;
- T1写入1,然后读取和写入3次.
- 然后T2写入1;
- 然后T1读为1;
- 然后T2-5完成所有工作
- 然后,最后,T1写入2.
(注意:如果每个线程至少有2个,结果2既不依赖于线程数,也不依赖于迭代数.)
(Note: the result 2 is not dependent either on the number of threads, or the number of iterations, provided there are at least 2 of each.)
But the honest answer to this is: it really doesn't matter. There is a data race, as defined in JLS 17.4.5:
当程序包含两个冲突的访问时(第17.4.1节[如果至少一个访问是写操作,则对同一变量的两次访问(读或写)被认为是冲突的.")没有按事前发生的顺序排序,据说其中包含数据竞争.
(线程中的动作之间没有 happens-before 关系)
(There is an absence of happens-before relationships between the actions in the threads)
所以您不能有效地依靠它所做的任何事情.这只是不正确的代码.
So you can't usefully rely on whatever it does. It is simply incorrect code.
(此外,我知道此问题的答案并不是因为一些来之不易的调试多线程代码或深入的技术阅读:我知道这一点是因为我之前在其他地方都已经阅读过此答案.这是一个客厅技巧,仅此而已,所以问最小值不是一个很好的面试问题).
(Moreover, I know the answer to this not because of some hard-won battle debugging multithreaded code, or deep technical reading: I know this because I have read this answer before elsewhere. It's a parlour trick, nothing more, and so asking the minimum value isn't a very good interview question).
这篇关于竞争条件:整数的最小和最大范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!