Java并发之不可思议的死循环详解

时间:2022-03-15 21:03:04

下面的代码将发生死循环

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.zzj.concurrency;
 
public class VolatileObjectTest implements Runnable{
 private ObjectA objectA; // 加上volatile 就可以正常结束While循环了
  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 {
     // 如果启动的时候加上-server 参数则会 输出 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;
    }
  
  }
}

死循环发生在代码段:

?
1
2
3
while (objectA.isFlag()) {
    i++;
}

这是由于编译器对其进行了优化,因为while循环内部没有修改objectA变量且没有用volatile修饰,JVM会把判断提前,类似于优化成如下:

?
1
2
3
4
5
if(objectA.isFlag()){
  while(true){
    i++;
  }
}

以上这篇Java并发之不可思议的死循环详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。