Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么要提前对方法中的局部变量进行垃圾收集?_Java_Garbage Collection_Executorservice_Stack Frame - Fatal编程技术网

Java 为什么要提前对方法中的局部变量进行垃圾收集?

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

这是一个多线程测试代码,每次创建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;
    }

}
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)