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++;
  }
}

Related articles: