I am trying to run a for loop inside an infinite while loop. The code doesn't run as intended when there's no print statement, but when there is a print statement, it runs fine. Here is the code:
class Test implements Runnable{
public static int varint = 0;
public static void main(String args[]){
Thread x = new Thread(new Test());
int i;
x.start();
while(true){
System.out.println("Hello World"); //If this isn't included,
//the exit statement isn't executed
for(i=0;i<varint;i++){
System.out.println("Exit");
System.exit(0);
}
}
}
public void run(){
try{
Thread.sleep(5000);
} catch(Exception e){
System.out.println("Caught");
}
varint = 1;
}
}
This is just a small example taken from a much bigger loop. How can I fix this?
Java while loop is a control flow statement that allows code to be executed repeatedly based on a given Boolean condition. The while loop can be thought of as a repeating if statement.
If it returns false, it will end the while loop. The Java Do-While loop is almost the same in While Loop. While loop executes the code inside the bracket if the condition statement returns to true, but in the Do-While loop, the code inside the do statement will always be called.
The difference lies in the fact that if the condition is true at the starting of the loop the statements would still be executed, however in case of while loop it would not be executed at all. This is an exit-controlled loop because of the fact that it checks the condition after the statements inside it are executed.
Looping statements are also common in programming. These are used if you are executing the same line of codes repeatedly. In order to minimize the lines of codes, we use looping statements. ? //enter your code here that will be called repeatedly. A Java For loop contains three parts inside the parenthesis.
You have a data race. One of the threads write to varint
and the other reads varint
with no explicit synchronization. varint
is not declared volatile. According to Java memory model, there is no guarantee the reading thread will ever see the that varint
was changed.
It works when you add the println
because println uses synchronization internally, which makes varint
visible to the running thread.
Either use a locking to read/write varint
, or declare it volatile
.
This is a good source for the Java memory model and volatiles:
http://tutorials.jenkov.com/java-concurrency/java-memory-model.html#visibility-of-shared-objects
The main thread executing the loop in this avatar is not guaranteed to see any updates to varint
. So varint
can be updated to 1 or 100 but there would still be no guarantees for main thread to be able to see the updates.
In order to guarantee memory visibility, use a volatile or synchronization primitives.
Please see the following link from an architect of Java 5 Concurrency. This article explains: "Status Flags and Volatile"
On the other hand, the reading thread in certain cases (intermittently as in your case when you add the print) might see the update and it might seem the program is behaving correctly. Such kind of visibility issues are extremely hard to track if it makes it to production.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With