Thread doesn't see changes of shared object inside while(){...}

XMLWordPrintable

    • Type: Bug
    • Resolution: Not an Issue
    • Priority: P4
    • None
    • Affects Version/s: 7u51
    • Component/s: other-libs
    • x86_64
    • linux

      FULL PRODUCT VERSION :
      java version "1.7.0_51"
      Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      3.12.8-200.fc19.x86_64, on Windows too

      A DESCRIPTION OF THE PROBLEM :
      2 Threads. One has method run with while(SomeSharedObject.field == STATE_0){ <content> } Then if in the other thread we do: thread2.start(); SomeSharedObject.field = STATE_1; and IT DOESN'T FINISH WHILE! except if <content> has yield() or sleep()!

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_51"
      Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Go.java:
      package lol;

      import java.lang.reflect.Field;

      import sun.misc.*;



      class Go{

      public int ini = 0;


      public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InterruptedException{

      Go ini = new Go();
      new A(ini).start(); // Thread 2

      Thread.sleep(2000);


      System.out.println("Changing value to 1");
      ini.ini = 1;// EXPECTING thread 2 to break from WHILE




      }


      }

      A.java
      package lol;

      import java.lang.reflect.Field;
      import sun.misc.Unsafe;


      public class A extends Thread{

      protected Go in;
      private long offset;
      private Unsafe usf;

      public A(Go in) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{

      this.in = in;
      Field ff = Unsafe.class.getDeclaredField("theUnsafe");
      ff.setAccessible(true);
      this.usf = (Unsafe)ff.get(null);
      this.offset = this.usf.objectFieldOffset(Go.class.getDeclaredField("ini"));

      }

      public void run(){

      while(this.in.ini == 0){ // ENDLESS!!...

      //System.out.println("Value is: " + ((Go)this.usf.getObject(this.in, this.offset)).ini);
      // System.out.println("Unsafe value is: " + (int)this.usf.getInt(this.in, this.offset) + "real is " + this.in.ini);
      /*...HACK: this helps btw:
      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {

      }*/
      }
      System.out.println("Unsafe value is: " + this.usf.getInt(this.in, this.offset) + "real is " + this.in.ini);
      System.out.println("Exit");
      }


      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Changing value to 1
      Unsafe value is: 1 real is 1
      Exit
      ACTUAL -
      Changing value to 1

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      No errors

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Go.java:
      package lol;

      import java.lang.reflect.Field;

      import sun.misc.*;



      class Go{

      public int ini = 0;


      public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InterruptedException{

      Go ini = new Go();
      new A(ini).start(); // Thread 2

      Thread.sleep(2000);


      System.out.println("Changing value to 1");
      ini.ini = 1;// EXPECTING thread 2 to break from WHILE




      }


      }

      A.java
      package lol;

      import java.lang.reflect.Field;
      import sun.misc.Unsafe;


      public class A extends Thread{

      protected Go in;
      private long offset;
      private Unsafe usf;

      public A(Go in) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{

      this.in = in;
      Field ff = Unsafe.class.getDeclaredField("theUnsafe");
      ff.setAccessible(true);
      this.usf = (Unsafe)ff.get(null);
      this.offset = this.usf.objectFieldOffset(Go.class.getDeclaredField("ini"));

      }

      public void run(){

      while(this.in.ini == 0){ // ENDLESS!!...

      //System.out.println("Value is: " + ((Go)this.usf.getObject(this.in, this.offset)).ini);
      // System.out.println("Unsafe value is: " + (int)this.usf.getInt(this.in, this.offset) + "real is " + this.in.ini);
      /*...HACK: this helps btw:
      try {
      Thread.sleep(1000);
      } catch (InterruptedException e) {

      }*/
      }
      System.out.println("Unsafe value is: " + this.usf.getInt(this.in, this.offset) + "real is " + this.in.ini);
      System.out.println("Exit");
      }


      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use Thread.sleep(~minimal_value~);

            Assignee:
            Unassigned
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: