Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8228899

While loop does not break on boolean condition

XMLWordPrintable

    • x86_64
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      OS - Ubuntu 18.04.1 LTS
      Tested with both java version - 1.8.0_121
      and java version - 12.0.2

      A DESCRIPTION OF THE PROBLEM :
      If the while body has a small number of instructions, then it won't break the while loop if the boolean condition changed externally.

      I found a similar issue - https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8179334
      however even when the while body is not empty, this can be reproducible,
      I have checked the bytecodes in this scenario, it seems for me jump instructions are correctly generated, hence I thought maybe some issue with the hotspot VM


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Code I have pasted in the source code section wouldn't exit the while loop.



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      While loop should exit
      ACTUAL -
      While loop keeps on running

      ---------- BEGIN SOURCE ----------
      public class Main {
           
              public static boolean classLevelVar = true;
              public static long fact;
           
              public static void main(String[] args) {
                      breakWhileUsingClassVar();
              }
              public static int breakWhileUsingClassVar() {
                      (new Thread(() -> {
                              try {
                                      Thread.sleep(2000);
                              } catch (InterruptedException e) {
                              }
                              classLevelVar = false;
           
                              System.out.println("After changing the class level variable - " + classLevelVar);
                      })).start();
                      System.out.println("Before starting the while loop - " + classLevelVar);
                      while (classLevelVar) {
                              for (int i = 2; i <= 999999999; i++) {
                                      fact = fact * i;
                              }
                              for (int i = 2; i <= 999999999; i++) {
                                      fact = fact * i;
                              }
                              //for (int i = 2; i <= 999999999; i++) {
                              // fact = fact * i;
                              //}
                      }
                      // Below statement doesn't get hit, making the class level variable volatile solves the issue.
                      return 8;
              }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      If you make the condition boolean "classLevelVar" volatile, then it works,
      and if you uncomment the last for loop, then it works, (Basically if the logic inside while body exceeds a certain threshold, this works properly)
      and if you put a SOUT inside the while loop, again it works.

      FREQUENCY : always


            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: