Java 为什么要提前对方法中的局部变量进行垃圾收集?
这是一个多线程测试代码,每次创建newSingleThreadExecutor时,另外两个线程不断触发gc。在HotSpot java8(1.8.0_221)下,将出现线程池已关闭的错误Java 为什么要提前对方法中的局部变量进行垃圾收集?,java,garbage-collection,executorservice,stack-frame,Java,Garbage Collection,Executorservice,Stack Frame,这是一个多线程测试代码,每次创建newSingleThreadExecutor时,另外两个线程不断触发gc。在HotSpot java8(1.8.0_221)下,将出现线程池已关闭的错误 public class ThreadPoolTest { public static void main(String[] args) { final ThreadPoolTest threadPoolTest = new ThreadPoolTest(); for
public class ThreadPoolTest {
public static void main(String[] args) {
final ThreadPoolTest threadPoolTest = new ThreadPoolTest();
for (int i = 0; i < 8; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Future<String> future = threadPoolTest.submit();
try {
String s = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
}
}
}).start();
}
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.gc();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.gc();
}
}
}).start();
}
public Future<String> submit() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
FutureTask<String> futureTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
Thread.sleep(50);
return System.currentTimeMillis() + "";
}
});
executorService.execute(futureTask);
return futureTask;
}
}
Executors.newSingleThreadExecutor创建一个自动关闭的线程池(java.util.concurrent.Executors.FinalizableDelegatedExecutorService),因此只能在收集对象之前关机执行
但根据错误日志,Executor服务提前关闭。与堆栈帧弹出之前一样,executorService的最终方法提前执行
为什么会发生这种情况?在每个执行器完成后,您从未关闭过它,因此我猜测您只是在积累越来越多的活动线程(每个空闲线程,但仍然存在),直到JVM无法为新的执行器创建新线程。但是从错误日志来看,这是由线程池关闭引起的,但是关闭只会在java.util.concurrent.Executors.FinalizableDelegatedExecutorService#finalize函数下执行。我想说的可能是它本身没有关闭,而是没有正确启动。感谢您的回答,我们已经发现了问题,这是jdk中的一个bug------
Exception in thread "Thread-2" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@a5acd19 rejected from java.util.concurrent.ThreadPoolExecutor@30890a38[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:668)
at ThreadPoolTest.submit(ThreadPoolTest.java:54)
at ThreadPoolTest$1.run(ThreadPoolTest.java:12)
at java.lang.Thread.run(Thread.java:748)