Xia*_* Xu 4 java multithreading daemon executor
我有一个对象需要定期做一些工作,而对象本身是活着的,所以我设计了类似下面的东西.基本上是一个Main类,它包含对ScheduledExecutorService实例的引用.在此示例中,所有定期工作都是将字符串打印到std.
我希望代码的行为如下:
但是,如果我运行这个程序,会发生什么,它会永远发生.基本上gc从不调用o1的终结器,因此,调度程序永远不会关闭,因此,即使主线程结束,程序仍然不会退出.
现在,如果我在test2()中注释掉o1.register,程序的行为就像它应该的那样,例如gc调用等.同样在调试器中,似乎只有在调用ScheduledExecutorService.schedule后才会创建一个实际的线程.
有什么解释发生了什么?
public class Main {
public static void main(String[] args) throws Exception {
    test2();
    System.gc();
    System.out.println("Waiting for finalize to be called..");
    Thread.sleep(5000);
}
private static void test2() throws Exception {
    Main o1 = new Main();
    o1.register();
    Thread.sleep(5000);     
}
private final ScheduledExecutorService _scheduler = Executors.newSingleThreadScheduledExecutor();   
private void register() {
    _scheduler.scheduleWithFixedDelay(new Runnable() { 
        @Override public void run() { 
            System.out.println("!doing stuff...");
            }
        }, 1, 1, TimeUnit.SECONDS);
}
@Override
protected void finalize() throws Throwable  {
    try {
        System.out.print("bye");
        _scheduler.shutdown();          
    } finally {
        super.finalize();
    }       
}
Run Code Online (Sandbox Code Playgroud)
}
两个问题:
System.gc()调用被定义为对JVM 的建议,而不是命令.API文档中的措辞是调用gc方法表明Java虚拟机花费了很多精力来回收未使用的对象...