使用 Callable 和 Future 程序不会退出
Program won't exit in using Callable and Future
IDE: IntelliJ
JDK: Java 11
在测试讲座中的示例代码时,我发现了一些非常奇怪的事情,即使没有任何循环,我的程序也不会停止!
import java.util.concurrent.Callable;
public class FindMaxTask implements Callable<Integer> {
private int[] data;
private int start;
private int end;
public FindMaxTask(int[] data, int start, int end) {
this.data = data;
this.start = start;
this.end = end;
}
public Integer call() {
int max = Integer.MIN_VALUE;
for (int i = start; i < end; i++) {
if (data[i] > max) {
max = data[i];
}
}
return max;
}
}
这是一个 FindMaxTask
,实现了 Callable
接口,该接口在给定的数组范围内执行查找最大值。
public static void testCallable() throws ExecutionException, InterruptedException {
final int dataSize = 10000;
int[] data = new int[dataSize];
Random random = new Random();
for (int i = 0; i < dataSize; i++) {
data[i] = random.nextInt(1000000);
}
FindMaxTask task0 = new FindMaxTask(data, 0, dataSize / 2);
FindMaxTask task1 = new FindMaxTask(data, dataSize / 2, dataSize);
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Integer> future0 = service.submit(task0);
Future<Integer> future1 = service.submit(task1);
int ret0 = future0.get();
int ret1 = future1.get();
System.out.println("ret0: " + ret0 + System.lineSeparator() + "ret1: " + ret1);
}
这是 Main class 中的一个 testCallable
静态函数。
如果我 运行 testCallable
在 main 函数中运行,程序会在控制台打印每个 ret 值后停止。
这个问题与Callable
或Future
有关吗? (在打印 ret0、ret1 之后,我尝试使用 true
的值调试 future1.isDone()
,所以很明显 chlid 线程似乎没有被阻塞)
请告诉我为什么会这样
您必须关闭线程池。否则,您在后台仍然有非守护线程 运行。在所有非守护线程停止之前,JVM 不会退出。
ExecutorService service = Executors.newFixedThreadPool(2);
try {
// do things with the executor service
} finally {
service.shutdown();
}
如果要阻塞直到所有任务完成,可以使用awaitTermination
, or call shutdown
and then loop until isTerminated
returns true. If you want to try to terminate any running or queued tasks immediately, you can use shutdownNow
。
IDE: IntelliJ
JDK: Java 11
在测试讲座中的示例代码时,我发现了一些非常奇怪的事情,即使没有任何循环,我的程序也不会停止!
import java.util.concurrent.Callable;
public class FindMaxTask implements Callable<Integer> {
private int[] data;
private int start;
private int end;
public FindMaxTask(int[] data, int start, int end) {
this.data = data;
this.start = start;
this.end = end;
}
public Integer call() {
int max = Integer.MIN_VALUE;
for (int i = start; i < end; i++) {
if (data[i] > max) {
max = data[i];
}
}
return max;
}
}
这是一个 FindMaxTask
,实现了 Callable
接口,该接口在给定的数组范围内执行查找最大值。
public static void testCallable() throws ExecutionException, InterruptedException {
final int dataSize = 10000;
int[] data = new int[dataSize];
Random random = new Random();
for (int i = 0; i < dataSize; i++) {
data[i] = random.nextInt(1000000);
}
FindMaxTask task0 = new FindMaxTask(data, 0, dataSize / 2);
FindMaxTask task1 = new FindMaxTask(data, dataSize / 2, dataSize);
ExecutorService service = Executors.newFixedThreadPool(2);
Future<Integer> future0 = service.submit(task0);
Future<Integer> future1 = service.submit(task1);
int ret0 = future0.get();
int ret1 = future1.get();
System.out.println("ret0: " + ret0 + System.lineSeparator() + "ret1: " + ret1);
}
这是 Main class 中的一个 testCallable
静态函数。
如果我 运行 testCallable
在 main 函数中运行,程序会在控制台打印每个 ret 值后停止。
这个问题与Callable
或Future
有关吗? (在打印 ret0、ret1 之后,我尝试使用 true
的值调试 future1.isDone()
,所以很明显 chlid 线程似乎没有被阻塞)
请告诉我为什么会这样
您必须关闭线程池。否则,您在后台仍然有非守护线程 运行。在所有非守护线程停止之前,JVM 不会退出。
ExecutorService service = Executors.newFixedThreadPool(2);
try {
// do things with the executor service
} finally {
service.shutdown();
}
如果要阻塞直到所有任务完成,可以使用awaitTermination
, or call shutdown
and then loop until isTerminated
returns true. If you want to try to terminate any running or queued tasks immediately, you can use shutdownNow
。