在使用ExecutorService在静态块中执行Callable时遇到一个奇怪的问题。让我们直接在下面看到完整的代码。
package com.acme;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class App {
private static int data = 0;
static {
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<String> future = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("" + data);
return "hello";
}
});
}
public static void main(String[] args) {
System.out.println("enter main scope");
}
}
运行main方法,结果如下图所示。
但是,如果我添加以下一些业务代码,则控制台中不会打印任何内容。
public class App {
private static int data = 0;
static {
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<String> future = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("" + data);
return "hello";
}
});
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("enter main scope");
}
}
任何人都可以提供有关此问题的帮助吗?更多细节。
答案 0 :(得分:0)
当您使执行程序代码在静态块中运行时,这甚至迫使代码甚至在App.class上下文完全创建之前就运行了(即,类未完全加载到内存中,或者您现在可以说“ data”变量不在内存中)。
基本上,当您的调用方法通过执行程序被调用时,它的(线程)试图在App.class中找到变量“ data”,但直到现在可能尚未加载,这也使线程无限运行。
解决方案:
在主块中运行执行程序,但仍然存在问题,假设如果由于某种原因(业务逻辑)卸载了App.class,您将再次陷入无限运行的线程中,该线程正在查找“数据”
使数据变量为“ final”,然后您可以将代码放置为静态块或静态方法(例如main)。至于最终变量,将保留一个单独的副本,并且不会出现类加载或卸载的问题。