-
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~);
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~);