我构建以下演示代码来测试java.util.concurrent.CompletableFuture.runAsync函数:
import java.util.ArrayList;
import java.util.List;
public class TestClass {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
java.util.concurrent.CompletableFuture.runAsync( () ->{startCall(1);});
java.util.concurrent.CompletableFuture.runAsync( () ->{startCall(2);});
java.util.concurrent.CompletableFuture.runAsync( () ->{startCall(3);});
//Add sleep if case mainthread is to fast
Thread.sleep(1000);
while (!RunningTasks.isEmpty());
System.out.println("Shutting down");
}
private static List<String> RunningTasks=new ArrayList<String>();
private static void startCall(int cn) {
RunningTasks.add("TASK"+cn);
int sleeptime = (int) (Math.random()*10*1000);
System.out.println("Sleeptimer: "+sleeptime+" for instance: "+cn);
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Task "+cn+" finished");
RunningTasks.remove("TASK"+cn);
System.out.println("RunningTasks: "+RunningTasks.size() +" is empty? "+RunningTasks.isEmpty());
}
}
如果我在正常模式下的日食中运行此代码(因此只需按一下运行),一切都可以预期,则while循环似乎永远不会真正停止,这意味着“关闭”永远不会被打印。
如果我在DebugMode中运行代码并在 RunningTasks:0为空时立即在条件上设置断点? true 被打印,而while检测到条件为假并退出。
如果我放了一些代码,例如将一个sysout命令放到while循环中,它也会像预期的那样退出。
我错过了什么吗,或者确实是Java错误吗?
答案 0 :(得分:2)
在运行代码时,可能会优化程序。因此,您的计算机可能会在while循环中缓存条件的结果。如果要防止这种缓存,可以编写:
private static volatile List<String> RunningTasks=new ArrayList<String>();
关键字 volatile
告诉计算机不要缓存结果,这样您就可以在每次迭代中真正查询RunningTasks.isEmpty()
的结果,而无需使用缓存的值。>