Why is this code not going into an infinite loop as suggested by JSR133?What is reflection and why is it useful?What is a serialVersionUID and why should I use it?How do I break out of nested loops in Java?Why is subtracting these two times (in 1927) giving a strange result?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Why is char[] preferred over String for passwords?Why is it faster to process a sorted array than an unsorted array?Why does this code using random strings print “hello world”?Why is printing “B” dramatically slower than printing “#”?Why is executing Java code in comments with certain Unicode characters allowed?

Can't connect to Internet in bash using Mac OS

Intuition behind eigenvalues of an adjacency matrix

Strange math syntax in old basic listing

Expenditure in Poland - Forex doesn't have Zloty

Where can I find the list of all tendons in the human body?

How do I subvert the tropes of a train heist?

Can a wire having a 610-670 THz (frequency of blue light) AC frequency supply, generate blue light?

Yandex programming contest: Alarms

Do you play the upbeat when beginning to play a series of notes, and then after?

Can a helicopter mask itself from Radar?

Term for checking piece whose opponent daren't capture it

What kind of appearance can I expect if I both overexpose and push film?

Socratic Paradox

Is floating in space similar to falling under gravity?

60s (or earlier) short story where each colony has one person who doesn't connect well with others who is there for being able to absorb knowledge

Differences between “pas vrai ?”, “c’est ça ?”, “hein ?”, and “n’est-ce pas ?”

Modern approach to radio buttons

Uncommanded roll at high speed

Why would Lupin kill Pettigrew?

What does it mean when you think without speaking?

Select row of data if next row contains zero

Looking after a wayward brother in mother's will

Can you move on your turn, and then use the Ready Action to move again on another creature's turn?

What was this black-and-white film set in the Arctic or Antarctic where the monster/alien gets fried in the end?



Why is this code not going into an infinite loop as suggested by JSR133?


What is reflection and why is it useful?What is a serialVersionUID and why should I use it?How do I break out of nested loops in Java?Why is subtracting these two times (in 1927) giving a strange result?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Why is char[] preferred over String for passwords?Why is it faster to process a sorted array than an unsorted array?Why does this code using random strings print “hello world”?Why is printing “B” dramatically slower than printing “#”?Why is executing Java code in comments with certain Unicode characters allowed?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















In JSR-133 section 3.1, which discusses the visibility of actions between threads - it is mentioned that the code example below, which does not utilise the volatile keyword for the boolean field, can become an infinite loop if two threads are running it. Here is the code from the JSR:



class LoopMayNeverEnd 
boolean done = false;
void work()
while (!done)
// do work


void stopWork()
done = true;




Here is a quote of the important bit in that section that I'm interested in:




... Now imagine that two threads are created, and that one
thread calls work(), and at some point, the other thread calls stopWork(). Because there is
no happens-before relationship between the two threads, the thread in the loop may never
see the update to done performed by the other thread ...




And here is my own Java code I wrote just so I can see it loop:



public class VolatileTest 
private boolean done = false;
public static void main(String[] args)
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();

private void runTest()
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();

private void stopWork()
done = true;
System.out.println("stopped work");

private void work()
while(!done)
System.out.println("started work");





Although the results from consecutive executions are different - as expected - I don't see it ever going into an infinite loop. I'm trying to understand how I can simulate the infinite loop that the documentation suggests, what am I missing? How does declaring the boolean volatile, remove the infinite loop?










share|improve this question

















  • 3





    Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

    – JB Nizet
    Mar 24 at 10:08












  • Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

    – drewdles
    Mar 24 at 10:13






  • 1





    It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

    – JB Nizet
    Mar 24 at 10:16











  • That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

    – drewdles
    Mar 24 at 10:24






  • 1





    No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

    – JB Nizet
    Mar 24 at 10:26

















1















In JSR-133 section 3.1, which discusses the visibility of actions between threads - it is mentioned that the code example below, which does not utilise the volatile keyword for the boolean field, can become an infinite loop if two threads are running it. Here is the code from the JSR:



class LoopMayNeverEnd 
boolean done = false;
void work()
while (!done)
// do work


void stopWork()
done = true;




Here is a quote of the important bit in that section that I'm interested in:




... Now imagine that two threads are created, and that one
thread calls work(), and at some point, the other thread calls stopWork(). Because there is
no happens-before relationship between the two threads, the thread in the loop may never
see the update to done performed by the other thread ...




And here is my own Java code I wrote just so I can see it loop:



public class VolatileTest 
private boolean done = false;
public static void main(String[] args)
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();

private void runTest()
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();

private void stopWork()
done = true;
System.out.println("stopped work");

private void work()
while(!done)
System.out.println("started work");





Although the results from consecutive executions are different - as expected - I don't see it ever going into an infinite loop. I'm trying to understand how I can simulate the infinite loop that the documentation suggests, what am I missing? How does declaring the boolean volatile, remove the infinite loop?










share|improve this question

















  • 3





    Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

    – JB Nizet
    Mar 24 at 10:08












  • Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

    – drewdles
    Mar 24 at 10:13






  • 1





    It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

    – JB Nizet
    Mar 24 at 10:16











  • That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

    – drewdles
    Mar 24 at 10:24






  • 1





    No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

    – JB Nizet
    Mar 24 at 10:26













1












1








1








In JSR-133 section 3.1, which discusses the visibility of actions between threads - it is mentioned that the code example below, which does not utilise the volatile keyword for the boolean field, can become an infinite loop if two threads are running it. Here is the code from the JSR:



class LoopMayNeverEnd 
boolean done = false;
void work()
while (!done)
// do work


void stopWork()
done = true;




Here is a quote of the important bit in that section that I'm interested in:




... Now imagine that two threads are created, and that one
thread calls work(), and at some point, the other thread calls stopWork(). Because there is
no happens-before relationship between the two threads, the thread in the loop may never
see the update to done performed by the other thread ...




And here is my own Java code I wrote just so I can see it loop:



public class VolatileTest 
private boolean done = false;
public static void main(String[] args)
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();

private void runTest()
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();

private void stopWork()
done = true;
System.out.println("stopped work");

private void work()
while(!done)
System.out.println("started work");





Although the results from consecutive executions are different - as expected - I don't see it ever going into an infinite loop. I'm trying to understand how I can simulate the infinite loop that the documentation suggests, what am I missing? How does declaring the boolean volatile, remove the infinite loop?










share|improve this question














In JSR-133 section 3.1, which discusses the visibility of actions between threads - it is mentioned that the code example below, which does not utilise the volatile keyword for the boolean field, can become an infinite loop if two threads are running it. Here is the code from the JSR:



class LoopMayNeverEnd 
boolean done = false;
void work()
while (!done)
// do work


void stopWork()
done = true;




Here is a quote of the important bit in that section that I'm interested in:




... Now imagine that two threads are created, and that one
thread calls work(), and at some point, the other thread calls stopWork(). Because there is
no happens-before relationship between the two threads, the thread in the loop may never
see the update to done performed by the other thread ...




And here is my own Java code I wrote just so I can see it loop:



public class VolatileTest 
private boolean done = false;
public static void main(String[] args)
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();

private void runTest()
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();

private void stopWork()
done = true;
System.out.println("stopped work");

private void work()
while(!done)
System.out.println("started work");





Although the results from consecutive executions are different - as expected - I don't see it ever going into an infinite loop. I'm trying to understand how I can simulate the infinite loop that the documentation suggests, what am I missing? How does declaring the boolean volatile, remove the infinite loop?







java multithreading concurrency volatile java-memory-model






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 24 at 10:04









drewdlesdrewdles

209110




209110







  • 3





    Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

    – JB Nizet
    Mar 24 at 10:08












  • Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

    – drewdles
    Mar 24 at 10:13






  • 1





    It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

    – JB Nizet
    Mar 24 at 10:16











  • That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

    – drewdles
    Mar 24 at 10:24






  • 1





    No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

    – JB Nizet
    Mar 24 at 10:26












  • 3





    Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

    – JB Nizet
    Mar 24 at 10:08












  • Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

    – drewdles
    Mar 24 at 10:13






  • 1





    It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

    – JB Nizet
    Mar 24 at 10:16











  • That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

    – drewdles
    Mar 24 at 10:24






  • 1





    No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

    – JB Nizet
    Mar 24 at 10:26







3




3





Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

– JB Nizet
Mar 24 at 10:08






Remove your println statements, and you'll probably have a program that never stops. But even if you don't, remember that just because something can happen, even once in a million times, doesn't mean that it will always happen. It can depend on your JVM, your OS, etc. You just don't have any guarantee that the thread will see the new boolean value. Which is very different from saying "you are guaranteed that the thread won't see it".

– JB Nizet
Mar 24 at 10:08














Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

– drewdles
Mar 24 at 10:13





Thanks for your comment. Removing the print statement in the while loop is enough to get it into an infinite loop... Now the program prints "stopped work" and then never ends. Where did the assignment to the boolean variable to true go?

– drewdles
Mar 24 at 10:13




1




1





It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

– JB Nizet
Mar 24 at 10:16





It went to the register, or memory cache of the CPU core used by the stopping thread, or even to the main memory. But the reading thread can continue to read it from its own CPU core memory cache, because the field is not marked as volatile.

– JB Nizet
Mar 24 at 10:16













That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

– drewdles
Mar 24 at 10:24





That makes sense. Final question, does declaring the boolean a volatile mean that stopWork() is always called first due to the happens-before relationship?

– drewdles
Mar 24 at 10:24




1




1





No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

– JB Nizet
Mar 24 at 10:26





No, not at all. It guarantees that if a thread has written a value to the volatile field, then another thread reading the vaue of the volatile field will see the written value, and not some previous value.

– JB Nizet
Mar 24 at 10:26












1 Answer
1






active

oldest

votes


















1














The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.



This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.



Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.



Basically if you want to reproduce infinite loop - just run your program in server mode:



java -server VolatileTest





share|improve this answer

























  • Adding -server as a vm argument didn't create an infinite loop

    – drewdles
    Mar 27 at 12:56











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/3.0/"u003ecc by-sa 3.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
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322624%2fwhy-is-this-code-not-going-into-an-infinite-loop-as-suggested-by-jsr133%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.



This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.



Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.



Basically if you want to reproduce infinite loop - just run your program in server mode:



java -server VolatileTest





share|improve this answer

























  • Adding -server as a vm argument didn't create an infinite loop

    – drewdles
    Mar 27 at 12:56















1














The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.



This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.



Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.



Basically if you want to reproduce infinite loop - just run your program in server mode:



java -server VolatileTest





share|improve this answer

























  • Adding -server as a vm argument didn't create an infinite loop

    – drewdles
    Mar 27 at 12:56













1












1








1







The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.



This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.



Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.



Basically if you want to reproduce infinite loop - just run your program in server mode:



java -server VolatileTest





share|improve this answer















The actual behavior is OS and JVM specific. For example, by default, Java runs in client mode on 32-bit Windows and in server mode on the Mac. In client mode the work method will terminate, but will not terminate in server mode.



This happens because of the Java server JIT compiler optimization. The JIT compiler may optimize the while loop, because it does not see the variable done changing within the context of the thread. Another reason of the infinite loop might be because one thread may end up reading the value of the flag from its registers or cache instead of going to memory. As a result, it may never see the change made by the another thread to this flag.



Essentially by adding volatile you make the thread owning done flag to not cache this flag. Thus, the boolean value is stored in common memory and therefore guarantees visibility. Also, by using volatile you disabling JIT optimization that can inline the flag value.



Basically if you want to reproduce infinite loop - just run your program in server mode:



java -server VolatileTest






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 24 at 19:52

























answered Mar 24 at 19:32









ZgurskyiZgurskyi

1,384179




1,384179












  • Adding -server as a vm argument didn't create an infinite loop

    – drewdles
    Mar 27 at 12:56

















  • Adding -server as a vm argument didn't create an infinite loop

    – drewdles
    Mar 27 at 12:56
















Adding -server as a vm argument didn't create an infinite loop

– drewdles
Mar 27 at 12:56





Adding -server as a vm argument didn't create an infinite loop

– drewdles
Mar 27 at 12:56



















draft saved

draft discarded
















































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.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322624%2fwhy-is-this-code-not-going-into-an-infinite-loop-as-suggested-by-jsr133%23new-answer', 'question_page');

);

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







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript