我在关闭应用程序时遇到问题,因为关闭应用程序后某些线程仍在运行。 有人可以帮我一些方法来阻止所有线程在后台执行,然后杀死主线程???
[EDITED]
关于javafx的问题,我注意到许多新开发人员正面临着管理Threads的问题。我想分享一下我为简化在javafx上管理线程的生活所做的工作。我已经基于Android的AsyncTask创建了一个AsyncTask类,它基本上以简单但有效的方式执行Android的相同操作。您可以在Github project
上找到有关它的更多信息答案 0 :(得分:32)
这里有三个选项 - 最简单的方法是简单地创建你的线程作为守护,这意味着当你的主程序结束时,所有守护线程也会终止。
Thread thread = new Thread();
thread.setDaemon(true);
这是最简单的,但缺点是你不会得到一个优雅的关闭(即线程将停止,你将没有机会执行资源管理等,这可能或可能不是你的问题)。
另一种方法是保持生成的线程,当程序收到关闭信号时,迭代线程并传入某种信号以表示它们也应该终止
volatile boolean shutdown = false;
public void shutdown() {
shutdown = true;
}
public void run() {
while(!shutdown) {
... do your work here
}
... perform any cleanup work here
(注意:为了清晰起见,忽略任何异常处理)
最后一个选项是在java.util.concurrent
中使用Executor框架ExecutorService executorService = Executors.newFixedThreadPool(10);
... assign/invoke tasks etc
... at some point later your program is told to shutdown
... shutdown in executor too
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS); // wait for 10s in this case
executorService.shutdownNow();
答案 1 :(得分:30)
更好的解决方法是在关闭请求上添加 EventHandler :
@Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent e) {
Platform.exit();
System.exit(0);
}
});
}
答案 2 :(得分:4)
覆盖您的应用程序类
//System.exit(0) This will close all timers and threads inside the Jar application...
@Override
public void stop() throws Exception {
super.stop(); //To change body of generated methods, choose Tools | Templates.
System.exit(0);
}
答案 3 :(得分:2)
java.util.concurrent
包的Executors是可行的方法。明确地:
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
return thread;
});
答案 4 :(得分:2)
Platform.exit()方法属于JavaFX上下文。 当您调用Platform.exit()时,将在上下文终止之前调用方法javafx.application.Application#stop()。 将stop()方法放入JavaFX上下文终止之前需要执行的所有操作。
使用System.exit(0)方法,应用程序突然终止。 此方法并不安全,因为如果您现在调用System.exit(0)并且Job仍在运行,可能正在数据库中执行写操作, 该应用程序将不等待作业执行,从而导致数据库损坏。
我有一个运行带有SpringBoot和线程池的JavaFX的应用程序。这就是我的处理方式。
//...
import javafx.application.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@SpringBootApplication
public class Main extends Application {
ConfigurableApplicationContext context;
ScheduledExecutorService scheduledExecutorService;
@Override
public void init() {
this.context = SpringApplication.run(getClass());
this.context.getAutowireCapableBeanFactory().autowireBean(this);
this.scheduledExecutorService = Executors.newScheduledThreadPool(10);
}
@Override
public void stop() throws Exception {
super.stop();
this.context.close();
this.scheduledExecutorService.shutdownNow();
}
// ...
}