Java concurrency: an incredibly circular explanation
- 2020-05-30 20:05:07
- OfStack
The following code will have an infinite loop:
package com.zzj.concurrency;
public class VolatileObjectTest implements Runnable{
private ObjectA objectA; // add volatile It can end normally While The loop
public VolatileObjectTest(ObjectA a) {
this.objectA = a;
}
public ObjectA getA() {
return objectA;
}
public void setA(ObjectA a) {
this.objectA = a;
}
@Override
public void run() {
long i = 0;
while (objectA.isFlag()) {
i++;
}
System.out.println("stop My Thread " + i);
}
public void stop() {
objectA.setFlag(false);
}
public static void main(String[] args) throws InterruptedException {
// If I add it when I start it up -server Parameters will be The output Java HotSpot(TM) Server VM
System.out.println(System.getProperty("java.vm.name"));
VolatileObjectTest test = new VolatileObjectTest(new ObjectA());
new Thread(test).start();
Thread.sleep(1000);
test.stop();
System.out.println("Main Thread " + test.getA().isFlag());
}
static class ObjectA {
private boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
}
The dead loop occurs in the code segment:
while (objectA.isFlag()) {
i++;
}
This is because the compiler optimizes it, because the while loop does not modify the objectA variable and does not modify the volatile. JVM will prejudge it, which is similar to the following:
if(objectA.isFlag()){
while(true){
i++;
}
}