Race condition: Min and Max range of an integerCan 2 threads incrementing the same variable 100 times operate in a way that the variable will be less than 100?What is a race condition?Fastest way to determine if an integer's square root is an integerHow do I generate random integers within a specific range in Java?How can I pad an integer with zeros on the left?Java Thread - i want to generate numbers in sequence eg: 1,2,3,4…so on (there will be 2 threads only )Multiple threads accessing inner classJava : URLConnection setRequestProperty range issue relying on multithreaded process?
How can conflict be conducted between nations when warfare is never an option?
Help me pair my left and right socks!
Could the Unarmed Knight be successful in a battle?
What does 我们已经帮您踩过了 mean in this peculiarly translated escalator sticker?
Do any countries have a pensions system funded entirely by past contributions, rather than current taxes?
Why did George Lucas set Star Wars in the past instead of the future?
What LEGO set do these bags come from
Can you create a 3 way many to many relationship between objects?
How can I unscrew the faucet nuts in the tight space behind my sink basin?
Why can't the molecules of an ideal gas have the same speed?
How am I ever going to be able to "vet" 120,000+ lines of Composer PHP code not written by me?
What is the common term to express the barrier of a balcony?
What are the ethical implications of lying to get into a course?
Can I be fired the same day that I hand in my notice?
Are there examples of democratic states peacefully changing their constitution without abiding by the rules spelled out in the former constitution?
Why doesn't the road lose its thickness to the tyre?
Is it safe to drink the water from the fountains found all over the older parts of Rome?
By what means does the King wage war?
How did the Druids learn the Greek language by the time of Caesar's campaign in Gaul?
Why should you have travel insurance?
ampersand "&" causes if-else-fi to fail
What specifically can swap do that RAM can't
What animals do we use, if any, to describe the opposite of "a dog", used for something of an inferior quality?
How do planes maintain constant speeds at cruise altitudes?
Race condition: Min and Max range of an integer
Can 2 threads incrementing the same variable 100 times operate in a way that the variable will be less than 100?What is a race condition?Fastest way to determine if an integer's square root is an integerHow do I generate random integers within a specific range in Java?How can I pad an integer with zeros on the left?Java Thread - i want to generate numbers in sequence eg: 1,2,3,4…so on (there will be 2 threads only )Multiple threads accessing inner classJava : URLConnection setRequestProperty range issue relying on multithreaded process?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
I was recently asked this question in an interview.
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();
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?
java multithreading race-condition
|
show 2 more comments
I was recently asked this question in an interview.
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();
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?
java multithreading race-condition
6
Thread 1 in it's first iteration (i == 0
) readsnum == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments0
to1
and stores it, thread 2 reads1
in it's last iteration, thread 2 reads this1
in it's last iteration, thread 1 does the rest, thread 2 increments1
to2
and terminates as well. Not sure if it can go below2
.
– Johannes Kuhn
Sep 29 at 10:55
14
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
Addingvolatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.
– Johannes Kuhn
Sep 29 at 11:02
2
@JohannesKuhnnum++
isn't atomic, so it doesn't even work withvolatile
.
– Andy Turner
Sep 29 at 11:09
2
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09
|
show 2 more comments
I was recently asked this question in an interview.
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();
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?
java multithreading race-condition
I was recently asked this question in an interview.
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();
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?
java multithreading race-condition
java multithreading race-condition
edited Oct 2 at 8:23
Anmol Singh Jaggi
asked Sep 29 at 10:45
Anmol Singh JaggiAnmol Singh Jaggi
5,3091 gold badge22 silver badges52 bronze badges
5,3091 gold badge22 silver badges52 bronze badges
6
Thread 1 in it's first iteration (i == 0
) readsnum == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments0
to1
and stores it, thread 2 reads1
in it's last iteration, thread 2 reads this1
in it's last iteration, thread 1 does the rest, thread 2 increments1
to2
and terminates as well. Not sure if it can go below2
.
– Johannes Kuhn
Sep 29 at 10:55
14
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
Addingvolatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.
– Johannes Kuhn
Sep 29 at 11:02
2
@JohannesKuhnnum++
isn't atomic, so it doesn't even work withvolatile
.
– Andy Turner
Sep 29 at 11:09
2
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09
|
show 2 more comments
6
Thread 1 in it's first iteration (i == 0
) readsnum == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments0
to1
and stores it, thread 2 reads1
in it's last iteration, thread 2 reads this1
in it's last iteration, thread 1 does the rest, thread 2 increments1
to2
and terminates as well. Not sure if it can go below2
.
– Johannes Kuhn
Sep 29 at 10:55
14
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
Addingvolatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.
– Johannes Kuhn
Sep 29 at 11:02
2
@JohannesKuhnnum++
isn't atomic, so it doesn't even work withvolatile
.
– Andy Turner
Sep 29 at 11:09
2
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09
6
6
Thread 1 in it's first iteration (
i == 0
) reads num == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments 0
to 1
and stores it, thread 2 reads 1
in it's last iteration, thread 2 reads this 1
in it's last iteration, thread 1 does the rest, thread 2 increments 1
to 2
and terminates as well. Not sure if it can go below 2
.– Johannes Kuhn
Sep 29 at 10:55
Thread 1 in it's first iteration (
i == 0
) reads num == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments 0
to 1
and stores it, thread 2 reads 1
in it's last iteration, thread 2 reads this 1
in it's last iteration, thread 1 does the rest, thread 2 increments 1
to 2
and terminates as well. Not sure if it can go below 2
.– Johannes Kuhn
Sep 29 at 10:55
14
14
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
Adding
volatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.– Johannes Kuhn
Sep 29 at 11:02
Adding
volatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.– Johannes Kuhn
Sep 29 at 11:02
2
2
@JohannesKuhn
num++
isn't atomic, so it doesn't even work with volatile
.– Andy Turner
Sep 29 at 11:09
@JohannesKuhn
num++
isn't atomic, so it doesn't even work with volatile
.– Andy Turner
Sep 29 at 11:09
2
2
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09
|
show 2 more comments
4 Answers
4
active
oldest
votes
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).
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee thata=num
happens beforeb=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.
– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
|
show 4 more comments
Your threads are updating a variable which is is not volatile that means it does not guarantee that every thread will see the updated value of num
. Let consider the below execution flow of threads:
Thread 1: 0->1->2 (2 iteration left)
Thread 2: 0->1->2->3 (1 iteration left)
Thread 3: 0->1->2->3 (1 iteration left)
Thread 4: 0->1->2->3 (1 iteration left)
Thread 5: 0->1->2->3 (1 iteration left)
At this point, Thread 1 flushes the value 2
of num to memory and Thread 2,3,4,5 decide to read the num
from the memory again (for any reason). Now:
Thread 1: 2->3->4 (completed 2 iteration)
Thread 2: 2->3 (completed 1 iteration)
Thread 3: 2->3 (completed 1 iteration)
Thread 4: 2->3 (completed 1 iteration)
Thread 5: 2->3 (completed 1 iteration)
Thread 1 flushes the value 4
to the memory and after that Theard 2,3,4.. flushes the value to the memory show the current value of the number will be 3
instead of 5
add a comment
|
In my opinion, it's quite impossible to reach 25 due to the lack of atomic operations (see Atomic Access in Java Tutorials).
All threads start at almost the same time, so every thread sees ThreadTest.num
value as 0
in the first iteration. Since there are 5 threads accessing the same variable in parallel, at the third iteration the threads are likely to see ThreadTest.num
value still as 1
or 2
and are going to increment wrongly to 2
or 3
.
Depending on hardware the final value is going to be lower or higher, the fastest ones might have the lowest values and the slowest ones the higher values. But still, my claim is the maximum value cannot reach 25.
EDIT (2019-10-07)
I tested myself in my machine (Core i5 HQ), indeed the final result reached 25
almost all the times. To understand better, I tested with a bigger number in for
loop:
for (int i = 0; i < 10000; i++)
num++;
Now, most of times, the final result was between 20000 and 30000, well far from 50000.
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
add a comment
|
Well, My answer would be Max 25, and Min 0, since all of your operations are increment, and you initialized it as 0.. I think the static non-volatile int is thrown in there to make you go into these thoughts about race conditions, but is there anything in there that would DECREMENT the number in any situation?
Edit: For what it's worth, this would be a typical distraction that they may expect you to be able to overcome in the real world, justifying such "trickery", there are a lot of red herrings!
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58154466%2frace-condition-min-and-max-range-of-an-integer%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
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).
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee thata=num
happens beforeb=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.
– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
|
show 4 more comments
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).
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee thata=num
happens beforeb=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.
– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
|
show 4 more comments
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).
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).
edited Oct 2 at 5:53
answered Sep 29 at 11:32
Andy TurnerAndy Turner
100k10 gold badges108 silver badges179 bronze badges
100k10 gold badges108 silver badges179 bronze badges
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee thata=num
happens beforeb=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.
– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
|
show 4 more comments
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee thata=num
happens beforeb=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.
– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,
int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee that a=num
happens before b=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.– matt
Sep 29 at 14:12
I thought the "happens before relation" is a single thread action. Eg. if in the main method you had,
int a = num; int b = num;
in the code it looks like a<=b because the b assignment happens after. The jvm does not guarantee that a=num
happens before b=num
? As opposed to this example being more of a general race condition where you don't know the order which each thread accesses the variables.– matt
Sep 29 at 14:12
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
@matt there is a happens-before relationship implied by program order, that is, within a single thread, things appear to happen in the order they are written. This just doesn't tell you anything useful about the values seen between threads.
– Andy Turner
Sep 29 at 14:39
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
Its like asking a structural engineer "here's a tower built out of cards. Please describe how many cards will be standing after a gust of wind comes along and collapses it."
– don bright
Sep 29 at 19:13
1
1
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
@DanChase I don't follow. All threads increment, and you wait for all threads to complete, so it can't stay at zero.
– Andy Turner
Sep 29 at 21:46
2
2
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
@Cristik what is the mechanism by which T1 is preempted and later resumes, that allows it not to loop 5 times?
– Andy Turner
Oct 1 at 22:58
|
show 4 more comments
Your threads are updating a variable which is is not volatile that means it does not guarantee that every thread will see the updated value of num
. Let consider the below execution flow of threads:
Thread 1: 0->1->2 (2 iteration left)
Thread 2: 0->1->2->3 (1 iteration left)
Thread 3: 0->1->2->3 (1 iteration left)
Thread 4: 0->1->2->3 (1 iteration left)
Thread 5: 0->1->2->3 (1 iteration left)
At this point, Thread 1 flushes the value 2
of num to memory and Thread 2,3,4,5 decide to read the num
from the memory again (for any reason). Now:
Thread 1: 2->3->4 (completed 2 iteration)
Thread 2: 2->3 (completed 1 iteration)
Thread 3: 2->3 (completed 1 iteration)
Thread 4: 2->3 (completed 1 iteration)
Thread 5: 2->3 (completed 1 iteration)
Thread 1 flushes the value 4
to the memory and after that Theard 2,3,4.. flushes the value to the memory show the current value of the number will be 3
instead of 5
add a comment
|
Your threads are updating a variable which is is not volatile that means it does not guarantee that every thread will see the updated value of num
. Let consider the below execution flow of threads:
Thread 1: 0->1->2 (2 iteration left)
Thread 2: 0->1->2->3 (1 iteration left)
Thread 3: 0->1->2->3 (1 iteration left)
Thread 4: 0->1->2->3 (1 iteration left)
Thread 5: 0->1->2->3 (1 iteration left)
At this point, Thread 1 flushes the value 2
of num to memory and Thread 2,3,4,5 decide to read the num
from the memory again (for any reason). Now:
Thread 1: 2->3->4 (completed 2 iteration)
Thread 2: 2->3 (completed 1 iteration)
Thread 3: 2->3 (completed 1 iteration)
Thread 4: 2->3 (completed 1 iteration)
Thread 5: 2->3 (completed 1 iteration)
Thread 1 flushes the value 4
to the memory and after that Theard 2,3,4.. flushes the value to the memory show the current value of the number will be 3
instead of 5
add a comment
|
Your threads are updating a variable which is is not volatile that means it does not guarantee that every thread will see the updated value of num
. Let consider the below execution flow of threads:
Thread 1: 0->1->2 (2 iteration left)
Thread 2: 0->1->2->3 (1 iteration left)
Thread 3: 0->1->2->3 (1 iteration left)
Thread 4: 0->1->2->3 (1 iteration left)
Thread 5: 0->1->2->3 (1 iteration left)
At this point, Thread 1 flushes the value 2
of num to memory and Thread 2,3,4,5 decide to read the num
from the memory again (for any reason). Now:
Thread 1: 2->3->4 (completed 2 iteration)
Thread 2: 2->3 (completed 1 iteration)
Thread 3: 2->3 (completed 1 iteration)
Thread 4: 2->3 (completed 1 iteration)
Thread 5: 2->3 (completed 1 iteration)
Thread 1 flushes the value 4
to the memory and after that Theard 2,3,4.. flushes the value to the memory show the current value of the number will be 3
instead of 5
Your threads are updating a variable which is is not volatile that means it does not guarantee that every thread will see the updated value of num
. Let consider the below execution flow of threads:
Thread 1: 0->1->2 (2 iteration left)
Thread 2: 0->1->2->3 (1 iteration left)
Thread 3: 0->1->2->3 (1 iteration left)
Thread 4: 0->1->2->3 (1 iteration left)
Thread 5: 0->1->2->3 (1 iteration left)
At this point, Thread 1 flushes the value 2
of num to memory and Thread 2,3,4,5 decide to read the num
from the memory again (for any reason). Now:
Thread 1: 2->3->4 (completed 2 iteration)
Thread 2: 2->3 (completed 1 iteration)
Thread 3: 2->3 (completed 1 iteration)
Thread 4: 2->3 (completed 1 iteration)
Thread 5: 2->3 (completed 1 iteration)
Thread 1 flushes the value 4
to the memory and after that Theard 2,3,4.. flushes the value to the memory show the current value of the number will be 3
instead of 5
edited Sep 29 at 11:17
answered Sep 29 at 11:11
Amit BeraAmit Bera
5,6681 gold badge10 silver badges31 bronze badges
5,6681 gold badge10 silver badges31 bronze badges
add a comment
|
add a comment
|
In my opinion, it's quite impossible to reach 25 due to the lack of atomic operations (see Atomic Access in Java Tutorials).
All threads start at almost the same time, so every thread sees ThreadTest.num
value as 0
in the first iteration. Since there are 5 threads accessing the same variable in parallel, at the third iteration the threads are likely to see ThreadTest.num
value still as 1
or 2
and are going to increment wrongly to 2
or 3
.
Depending on hardware the final value is going to be lower or higher, the fastest ones might have the lowest values and the slowest ones the higher values. But still, my claim is the maximum value cannot reach 25.
EDIT (2019-10-07)
I tested myself in my machine (Core i5 HQ), indeed the final result reached 25
almost all the times. To understand better, I tested with a bigger number in for
loop:
for (int i = 0; i < 10000; i++)
num++;
Now, most of times, the final result was between 20000 and 30000, well far from 50000.
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
add a comment
|
In my opinion, it's quite impossible to reach 25 due to the lack of atomic operations (see Atomic Access in Java Tutorials).
All threads start at almost the same time, so every thread sees ThreadTest.num
value as 0
in the first iteration. Since there are 5 threads accessing the same variable in parallel, at the third iteration the threads are likely to see ThreadTest.num
value still as 1
or 2
and are going to increment wrongly to 2
or 3
.
Depending on hardware the final value is going to be lower or higher, the fastest ones might have the lowest values and the slowest ones the higher values. But still, my claim is the maximum value cannot reach 25.
EDIT (2019-10-07)
I tested myself in my machine (Core i5 HQ), indeed the final result reached 25
almost all the times. To understand better, I tested with a bigger number in for
loop:
for (int i = 0; i < 10000; i++)
num++;
Now, most of times, the final result was between 20000 and 30000, well far from 50000.
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
add a comment
|
In my opinion, it's quite impossible to reach 25 due to the lack of atomic operations (see Atomic Access in Java Tutorials).
All threads start at almost the same time, so every thread sees ThreadTest.num
value as 0
in the first iteration. Since there are 5 threads accessing the same variable in parallel, at the third iteration the threads are likely to see ThreadTest.num
value still as 1
or 2
and are going to increment wrongly to 2
or 3
.
Depending on hardware the final value is going to be lower or higher, the fastest ones might have the lowest values and the slowest ones the higher values. But still, my claim is the maximum value cannot reach 25.
EDIT (2019-10-07)
I tested myself in my machine (Core i5 HQ), indeed the final result reached 25
almost all the times. To understand better, I tested with a bigger number in for
loop:
for (int i = 0; i < 10000; i++)
num++;
Now, most of times, the final result was between 20000 and 30000, well far from 50000.
In my opinion, it's quite impossible to reach 25 due to the lack of atomic operations (see Atomic Access in Java Tutorials).
All threads start at almost the same time, so every thread sees ThreadTest.num
value as 0
in the first iteration. Since there are 5 threads accessing the same variable in parallel, at the third iteration the threads are likely to see ThreadTest.num
value still as 1
or 2
and are going to increment wrongly to 2
or 3
.
Depending on hardware the final value is going to be lower or higher, the fastest ones might have the lowest values and the slowest ones the higher values. But still, my claim is the maximum value cannot reach 25.
EDIT (2019-10-07)
I tested myself in my machine (Core i5 HQ), indeed the final result reached 25
almost all the times. To understand better, I tested with a bigger number in for
loop:
for (int i = 0; i < 10000; i++)
num++;
Now, most of times, the final result was between 20000 and 30000, well far from 50000.
edited Oct 7 at 13:10
answered Oct 5 at 22:35
Wagner MacedoWagner Macedo
5373 silver badges5 bronze badges
5373 silver badges5 bronze badges
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
add a comment
|
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Well I actually ran the program multiple times and it was printing 25 most of the times.
– Anmol Singh Jaggi
Oct 6 at 4:12
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
Hmmm, I answered without testing. Now that I evaluated myself, I see you are right, which don't make sense to me. Maybe that's because the loop is so small and the code run in a fresh JVM every time.
– Wagner Macedo
Oct 7 at 12:59
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
I added a note about my error and a test with a bigger number.
– Wagner Macedo
Oct 7 at 13:12
add a comment
|
Well, My answer would be Max 25, and Min 0, since all of your operations are increment, and you initialized it as 0.. I think the static non-volatile int is thrown in there to make you go into these thoughts about race conditions, but is there anything in there that would DECREMENT the number in any situation?
Edit: For what it's worth, this would be a typical distraction that they may expect you to be able to overcome in the real world, justifying such "trickery", there are a lot of red herrings!
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
add a comment
|
Well, My answer would be Max 25, and Min 0, since all of your operations are increment, and you initialized it as 0.. I think the static non-volatile int is thrown in there to make you go into these thoughts about race conditions, but is there anything in there that would DECREMENT the number in any situation?
Edit: For what it's worth, this would be a typical distraction that they may expect you to be able to overcome in the real world, justifying such "trickery", there are a lot of red herrings!
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
add a comment
|
Well, My answer would be Max 25, and Min 0, since all of your operations are increment, and you initialized it as 0.. I think the static non-volatile int is thrown in there to make you go into these thoughts about race conditions, but is there anything in there that would DECREMENT the number in any situation?
Edit: For what it's worth, this would be a typical distraction that they may expect you to be able to overcome in the real world, justifying such "trickery", there are a lot of red herrings!
Well, My answer would be Max 25, and Min 0, since all of your operations are increment, and you initialized it as 0.. I think the static non-volatile int is thrown in there to make you go into these thoughts about race conditions, but is there anything in there that would DECREMENT the number in any situation?
Edit: For what it's worth, this would be a typical distraction that they may expect you to be able to overcome in the real world, justifying such "trickery", there are a lot of red herrings!
answered Sep 29 at 19:40
Dan ChaseDan Chase
6363 silver badges11 bronze badges
6363 silver badges11 bronze badges
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
add a comment
|
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
I believe the asker / interviewer wants to know what the minimum and maximum will be at the end (even if the question didn't make this explicit). Otherwise the question would be trivial and probably not asked in an interview.
– Dukeling
Sep 29 at 20:00
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
@Dukeling I would agree if it didn't initialize to 0.. min set of the following [0,1,2,3] is 0, no? Could be wrong, who really knows what they wanted anyway :) You may be right. edit: for what it's worth, I would ask this question specifically to see if the person lived "in the weeds". Another use for the question (more legitimate in my view) would be for them to demonstrate how they analyze it, versus a particular answer, since it seems it could be anything between 0 and 25 depending on factors/timings/etc.
– Dan Chase
Sep 29 at 20:24
add a comment
|
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58154466%2frace-condition-min-and-max-range-of-an-integer%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
6
Thread 1 in it's first iteration (
i == 0
) readsnum == 0
, then all the other threads do their thing, except thread 2, who only did the first 4 iterations. Then thread 1 resumes, increments0
to1
and stores it, thread 2 reads1
in it's last iteration, thread 2 reads this1
in it's last iteration, thread 1 does the rest, thread 2 increments1
to2
and terminates as well. Not sure if it can go below2
.– Johannes Kuhn
Sep 29 at 10:55
14
The honest answer to this is: it doesn't really matter. There is a data race, so you can't usefully rely on whatever it does. It is simply incorrect code.
– Andy Turner
Sep 29 at 11:01
Adding
volatile
would make this program sequentially consistent, so there is no "race" in from the VM point of view.– Johannes Kuhn
Sep 29 at 11:02
2
@JohannesKuhn
num++
isn't atomic, so it doesn't even work withvolatile
.– Andy Turner
Sep 29 at 11:09
2
Did you ask the interviewer: How is that possible?
– Abra
Sep 29 at 12:09