java - 为什么方法中的局部变量会提前被垃圾收集?
问题描述
这是一个多线程测试代码,每次创建一个newSingleThreadExecutor,另外两个线程不断触发gc。HotSpot java8(1.8.0_221)下会出现线程池已关闭的错误。
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;
}
}
运行一段时间后会报错:
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)
Executors.newSingleThreadExecutor 创建一个自动关闭的线程池(java.util.concurrent.Executors.FinalizableDelegatedExecutorService),所以它应该只在对象被收集之前执行关闭。
但是从错误日志来看,executorService被提前关闭了。和栈帧弹出之前一样,executorService 的finalized 方法提前执行了。
为什么会这样?
解决方案
推荐阅读
- python - Pandas df.str.split() 仅在第一个元素上
- string - Delphi strToint64 初始值为零
- visual-studio - 使用参数启动外部程序(在 Visual Studio - 调试属性中)
- java - 我如何从父母(用户)的登录中获取信息
- python-3.x - 提交按钮在刽子手游戏中不起作用(Python)
- dart - 如何在 Flutter 中为自定义 AppBar 设置动画?
- google-bigquery - BigQuery - 执行从 SQL 查询生成的 SQL 查询
- java - 我有一个 ArrayIndexOutOfBoundsException 错误
- powershell - Powershell Join-Path 在结果中显示 2 个目录而不是 1 - 意外脚本/函数输出
- intellij-idea - 如何在idevim中进行不区分大小写的搜索(使用/和?)