当线程可以完成任务时,我是否需要使用JavaFX中的线程和任务在后台运行某些程序? [英] Do I need to use thread and a task in JavaFX to run something in background when a thread will do the job?

查看:137
本文介绍了当线程可以完成任务时,我是否需要使用JavaFX中的线程和任务在后台运行某些程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个线程定期运行三秒钟的背景动画.
我从用Swing编写的Thread Demo示例中修改了有问题的代码,并使用了 它替代了使用线程和任务的不太有效的早期版本.

I'm using a thread to periodically run a three second background animation.
I adapted the code in question from a Thread Demo example written in Swing and used it to replace a not quite working earlier version that used both a thread and a task.

播放视频或播放动画时,我的程序停止/暂停线程 并在结束视频或动画时开始一个新线程.这似乎没有 任何缺点,这就是为什么我不知道为什么以前的JavaFX搜索没有出现的原因 与我正在使用的解决方案类似的解决方案.似乎是一种相当直接的跑步方法 简短的背景动画.

My program stops/suspends the thread when either playing a video or running an animation and starts a new thread when ending the video or animation. This seems to work without any downside which is why I'm puzzled why my earlier JavaFX searches hadn't turned up a similar solution to the one I'm using. It seems a rather direct approach for running short, simple background animations.

我在哪里出错呢?我想念什么?我将如何重写此代码 同时使用线程和任务还是需要?

Where am I going wrong with this? What am I missing? How would I rewrite this code using both a Thread and a Task or do I need to?

我应该添加-while和run语句与原始语句基本保持不变 对Swing代码的唯一重要补充是添加thread.setDaemon(true) 进入startThread().

I should add - the while and run statements are virtually unchanged from the original and the only significant addition to the Swing code was to add thread.setDaemon( true ) to startThread().

播客侦听器.

// background thread
class BackGround extends Thread {
    @Override
    public void run() {
        while ( suspend.getValue() == false ) {
            try {
                 int r = shared.randInt( 5, 10 );
                 Thread.sleep( r * 1000 );            
            } catch ( InterruptedException e ) {
                // do nothing
        }
        if ( suspend.getValue() == false )  {
            Platform.runLater( () -> { 
                 int g = shared.cssGradients.length - 1;
                 g = shared.randInt( 0, g );       
                 gradientColor.set( shared.cssGradients[g] );
                 Boolean bif = shared.updatePanes( shared.cssGradients[g], 
                                      leftPane, rightPane );   

            });
        }
      }
    }   
}   // class background

// start thread
public synchronized void startThread() {
    thread = new BackGround();  // Thread thread ...defined elsewhere
    thread.setDaemon( true );
    thread.start();
}

// stop thread
public synchronized void stopThread() {
    suspend.set( true );
}

推荐答案

Task类对JavaFX有用的原因是它提供了许多回调,例如succeeded()failed()cancelled()和方法像updateProgress()updateMessage()这样将在JavaFX Application线程中运行,因此无需使用Platform.runLater( () -> { ... });即可更新UI.这使Task类成为执行后台任务(如下载数据或长时间运行的计算)的理想选择.

The reason the Task class is useful for JavaFX is that it provides a number of callbacks like succeeded(), failed() or cancelled() and methods like updateProgress() and updateMessage() that will run in the JavaFX Application thread and therefore let you update the UI without Platform.runLater( () -> { ... }); This makes the Task class a perfect choice for doing background tasks like downloading data or long running computations.

但是,由于您的线程只是在没有真正完成其工作的情况下连续运行,因此似乎不需要使用Task可以通过简单的Thread为您提供的任何其他功能.

However, since your thread simply runs continuously without ever really finishing its work, it doesn't seem that you would need any of the additional functionality a Task would provide you with over a simple Thread.

仍然,如果您真的想将代码转换为使用Task,它将看起来像这样:

Still, if you really wanted to convert your code to use a Task, it would look just like this:

class BackGround extends Task<Void> {

    @Override
    protected Void call() throws Exception {
        while (suspend.getValue() == false) {
            try {
                int r = shared.randInt(5, 10);
                Thread.sleep(r * 1000);
            } catch (InterruptedException e) {
                // do nothing
            }
            if (suspend.getValue() == false) {
                Platform.runLater(() -> {
                    int g = shared.cssGradients.length - 1;
                    g = shared.randInt(0, g);
                    gradientColor.set(shared.cssGradients[g]);
                    Boolean bif = shared.updatePanes(shared.cssGradients[g],
                            leftPane, rightPane);

                });
            }
        }
        return null;
    }
}

// start thread
public synchronized void startThread() {
    Task<Void> bg = new BackGround();
    Thread taskThread = new Thread(bg);
    taskThread.setDaemon(true);
    taskThread.start();
}

// stop thread
public synchronized void stopThread() {
    suspend.set( true );
}

如您所见,它确实对您没有任何影响,因为您不需要Thread不能给您的任何东西.但是,如果您想与UI线程进行更紧密的通信,例如显示进度条或显示状态更新,然后Task将为您提供执行此操作的工具.

As you see, it really doesn't make a difference for you, as you don't need anything that a Thread couldn't give you. If however you wanted to have closer communication with the UI thread, e.g. showing a progress bar or showing status updates, then a Task would give you the tools to do that.

我想也值得一提的是,Timeline的使用非常适合触发动画.看起来像这样:

I guess its also worth mentioning that the use of a Timeline would be quite elegant for triggering your animations. It would look somewhat like this:

Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        int g = shared.cssGradients.length - 1;
        g = shared.randInt(0, g);
        gradientColor.set(shared.cssGradients[g]);
        Boolean bif = shared.updatePanes(shared.cssGradients[g], leftPane, rightPane);
    }
}
));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();

handle()方法中的代码在JavaFX Application线程中每秒运行一次.不幸的是,这只能让您设置两次执行之间的固定时间,而您似乎想每次都等待随机的时间.

The code inside the handle() method is run every second in the JavaFX Application thread. Unfortunately this only lets you set a fixed time between executions, while you seem to want to wait a random amount of time each time.

TL; DR:可以使用Thread,因为在用例中不需要Task的其他功能.

TL;DR: Using a Thread is ok, because you don't need the additional functionalities of a Task in your use case.

这篇关于当线程可以完成任务时,我是否需要使用JavaFX中的线程和任务在后台运行某些程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆