我在我的程序中有一个预定的任务,它在给定的时间之后关闭一个框架。但是,在任务执行之后,程序继续运行,就好像ScheduledExecutorService仍然运行在不同的线程上一样。
这是我代码的相关部分:
int delay = 1000;
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.schedule(() -> {
System.out.println("executed");
getWindow().closeWindow();
// ex.shutdown();
}, delay, TimeUnit.MILLISECONDS);在这里,任务在1秒延迟后执行,“执行”被打印一次,框架关闭,程序甚至在这段代码之后继续运行。如果我取消对ex.shutdownNow();的注释,程序就会成功地按预期结束。不过,我不明白为何会出现这种情况。我也没有从其他互联网上找到任何东西。
MCVE:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
int delay = 1000;
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.schedule(() -> {
System.out.println("executed");
// ex.shutdown();
}, delay, TimeUnit.MILLISECONDS);
}
}lambdas可能已经分发了它,但这确实是Java 8。
为什么程序在任务执行之后不停止?
发布于 2014-12-10 02:35:48
由ScheduledExecutorService返回的Executors#newSingleThreadScheduledExecutor()线程池使用非守护进程线程。在关闭线程池之前,这些线程池仍在等待任务。当非守护进程线程处于活动状态时,JVM不会结束。
您可以使用重载的Executors#newSingleThreadScheduledExecutor(ThreadFactory)并提供自己的ThreadFactory实现,这将创建守护进程线程。请注意,这可能会导致您的任务甚至无法运行,因为JVM将在任务预定时间之前退出。
照你发现的做然后关闭它。请注意,您应该始终在安全的地方关闭它,在那里操作不会失败。
发布于 2014-12-10 02:58:58
Java虚拟机运行到所有不是守护进程线程的线程都死了。Executors.defaultThreadFactory()将每个新线程创建为非守护进程线程。但是,如果您想要朝着这个方向冒险的话,会有一个过载的Executors.newSingleThreadScheduledExecutor();,它以一个ThreadFactory作为参数。
public static void main(String[] args) {
int delay = 1000;
class DaemonFactory implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
ThreadFactory tf = new DaemonFactory();
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(tf);
ex.schedule(() -> {
System.out.println("executed");
}, delay, TimeUnit.MILLISECONDS);
}发布于 2014-12-10 03:16:34
我会完全以不同的方式对待这件事。你说:
我在我的程序中有一个预定的任务,它在给定的时间之后关闭一个框架。
为什么不为此使用一个Swing计时器,因为它是为很好地处理Swing事件线程而构建的?
new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
((Timer) e.getSource()).stop();
someWindow.dispose();
}
}).start();https://stackoverflow.com/questions/27392389
复制相似问题