I claim the minimum value possible is 2.
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.
Call the threads T1..T5:
- T1 reads 0, T2 reads 0;
- T1 writes 1, and then reads and writes 3 times.
- Then T2 writes 1;
- Then T1 reads 1;
- Then T2-5 do all of their work
- Then, finally, T1 writes 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:
When a program contains two conflicting accesses (§17.4.1 [“Two accesses to (reads of or writes to) the same variable are said to be conflicting if at least one of the accesses is a write.”]) that are not ordered by a happens-before relationship, it is said to contain a data race.
(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).