我是靠谱客的博主 闪闪溪流,这篇文章主要介绍java fx 线程_关于多线程:如果FX线程在Java中终止,则终止线程的最有效方法,现在分享给大家,希望可以做个参考。

我编写了一个简单的JavaFX应用程序,该应用程序显然在FX应用程序线程上运行。 该应用程序需要在单独的线程(不是FX线程)上运行的无限循环中进行一些后台处理,在固定的时间间隔后,我调用Platform.runLater()来更新FX应用程序的gui控件。

如果我关闭FX Gui应用程序,则后台线程将继续执行它。

为了在FX线程终止后终止后台线程,我现在在后台线程的while循环中使用fxThread.isAlive()。

这样,当while循环条件变为false时,一旦FX线程终止,后台线程就会自动终止。

这是一个不好的选择吗? 完成同一任务的替代方法和有效方法有哪些?

//imports

public class SimpleClockFX implements Application{

Thread fxThread;

//other variables

@Override

public void start(Stage primaryStage){

fxThread = Thread.currentThread();

//other stuff...

new Thread(()->{

//logic...

while(fxThread.isAlive()){

//logic...

Platform.runLater(()->{

//update gui controls

});

}

}).start();

}

可能是codereview.stackexchange.com的问题

如何终止FX应用程序,以及如何启动后台线程? 我也想你没有通过thread.setDaemon(true)

请在您的问题而不是评论中发布更改

主类正在实现javafx.application.Application。 在覆盖的方法start(Stage stage)中,我将后台线程创建为:new Thread(()-> {// logic here})。start();

实际上,注释是在完成之前通过按Enter键意外发布的。

好的,我想我有您的问题,请查看答案

如果线程不需要在终止时进行任何清理,则只需将该线程设为守护线程:

thread.setDaemon(true)

Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.

This method must be invoked before the thread is started.

到目前为止,使用setDaemon()是最容易的事情,如果处理线程不需要在应用程序退出之前进行任何清理(例如,它不需要完成或回滚原子提交事务),则建议使用setDaemon()。

如果需要在线程退出之前对其进行清理,则最好不要将该线程设为守护程序,而应使该线程可中断,发出中断并处理该中断。

例如,使用ExecutorService管理线程,使用与ExecutorService javadoc中提到的方法类似的方法在Application stop()方法中关闭该线程:

void shutdownAndAwaitTermination(ExecutorService pool) {

pool.shutdown(); // Disable new tasks from being submitted

try {

// Wait a while for existing tasks to terminate

if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {

pool.shutdownNow(); // Cancel currently executing tasks

// Wait a while for tasks to respond to being cancelled

if (!pool.awaitTermination(60, TimeUnit.SECONDS))

System.err.println("Pool did not terminate");

}

} catch (InterruptedException ie) {

// (Re-)Cancel if current thread also interrupted

pool.shutdownNow();

// Preserve interrupt status

Thread.currentThread().interrupt();

}

}

请注意,shutdownNow()调用将中断隐式发送到您的线程,除非将线程处理器显式编码为处理该中断,否则该中断将无效。

typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.

如果取消操作确实不起作用,而您只想放弃,则可以将上述代码中的System.err.println()语句替换为System.exit()。

而且您的线程任务逻辑还需要处理中断:

public class PrimeProducer extends Thread {

private final BlockingQueue queue;

PrimeProducer(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

BigInteger p = BigInteger.ONE;

while (!Thread.currentThread().isInterrupted())

queue.put(p = p.nextProbablePrime());

} catch (InterruptedException consumed) {

/* Allow thread to exit */

}

}

public void cancel() { interrupt(); }

}

另请注意,如果您不是子类化Thread,而是为库类型代码实现Runnable,则您不想像上面那样吞下中断,而是想恢复被中断的状态,类似于下面的内容(请阅读"下面的"处理InterruptedException",以进一步了解为什么需要对库代码恢复中断状态):

public class TaskRunner implements Runnable {

private BlockingQueue queue;

public TaskRunner(BlockingQueue queue) {

this.queue = queue;

}

public void run() {

try {

while (true) {

Task task = queue.take(10, TimeUnit.SECONDS);

task.execute();

}

}

catch (InterruptedException e) {

// Restore the interrupted status

Thread.currentThread().interrupt();

}

}

}

另请参阅一些参考文档(从中复制并粘贴了此答案中的某些信息):

Java中的Daemon线程是什么?

处理InterruptedException

javafx.concurrent.Task javadoc-提供有关守护程序状态设置和其他用于在JavaFX应用程序上下文中实现可取消任务的机制的有用信息。

那是非常有益的。 非常感谢 :)

通过调用fxThread.isAlive()并不是最好的解决方案,因为在最坏的情况下,您的fxThread可能会死,而线程已经通过了fxThread.isAlive()并在输入Platform.runLater时会给您一个异常,除非这是您案件的适当终止

尝试在顶级阶段为close事件添加一个侦听器。

还要调用System.exit(0)以完全终止JVM或您想要的任何自定义终止方法(例如,如果后台线程仍在运行,则显式导致对后台线程的中断)。

@Override

public void start(Stage primaryStage)

{

primaryStage.setOnCloseRequest(new EventHandler() {

public void handle(WindowEvent we) {

System.out.println("Stage is closing");

System.exit(0);

}

});

primaryStage.setTitle("Hello World!");

//      add your components

primaryStage.show();

//      not daemon

new Thread(new CustomRunnable()).start();

}

private static class CustomRunnable implements Runnable

{

public void run()

{

while(true){

//              long operation

}

}

}

编辑:

根据@ lostsoul29 comment,该方案意味着生成线程将不是守护程序线程。如果任何线程被标记为守护程序,则将需要自定义终止/处理。

似乎很好。。。不知道setOnCloseRequest()存在。 我已经添加了以下代码段:primaryStage.setOnCloseRequest((WindowEvent we)-> {System.exit(0);}); 并将while循环条件更新为" true" ...并且工作正常。 谢谢 :)

System.exit(0)不会杀死所有产生的子线程。 您必须依次关闭每个线程,然后退出应用程序。

@ lostsoul29,看来您还不太清楚问题/答案。 首先,您可以参考下面的链接,如果仍然遇到问题,请给我们一个新的问题。 线程生命周期setDaemon()

最后

以上就是闪闪溪流最近收集整理的关于java fx 线程_关于多线程:如果FX线程在Java中终止,则终止线程的最有效方法的全部内容,更多相关java内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(103)

评论列表共有 0 条评论

立即
投稿
返回
顶部