【问题标题】:Multithreading using Callable while having a responsive graphical interface在具有响应式图形界面的同时使用 Callable 进行多线程
【发布时间】:2016-11-26 20:34:20
【问题描述】:

我正在尝试在执行 cmd 命令时获得响应式 JavaFX 图形界面。
我正在执行的命令如下。

youtube-dl.exe --audio-format mp3 --extract-audio https://www.youtube.com/watch?v=l2vy6pJSo9c

如您所见,这是一个 youtube 下载器,可将 youtube 链接转换为 mp3 文件。 我希望它在第二个线程中执行,而不是在主 FX 线程中。

我通过在 StartDownloadingThread 类中实现接口 Callable 解决了这个问题。

 @Override
public Process call() throws Exception {
     Process p = null;
     p = ExecuteCommand(localCPara1, localCPara2, localDirectory).start();
    try {
        Thread.sleep(30);
    }catch (InterruptedException e){}
    return p;
}

ExecuteCommand 方法只返回一个ProcessBuilder 对象。

我尝试使用Thread.sleep 使程序返回到主线程,从而使应用程序响应。不幸的是,程序仍然冻结。

这就是方法调用的调用方式。

ExecutorService pool = Executors.newFixedThreadPool(2);
StartDownloadingThread callable =  new StartDownloadingThread(parameter1, parameter2, directory);
Future future = pool.submit(callable);
Process p = (Process) future.get();
p.waitFor();

如何使用Callable 界面使我的 GUI 响应?

【问题讨论】:

    标签: javafx executorservice callable youtube-dl


    【解决方案1】:

    使用执行器运行任务只是为了使用提交任务时返回的Futureget 方法实际上并没有释放原始线程以继续执行其他任务。后来你甚至在原始线程上使用waitFor 方法,这可能比你在Callable 中所做的任何事情都花费更多的时间。

    为此,Task class 可能更适合,因为它允许您使用事件处理程序处理应用程序线程上的成功/失败。

    另外,请确保在您完成提交任务后关闭ExecutorService

    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            Process p = null;
            p = ExecuteCommand(localCPara1, localCPara2, localDirectory).start();
    
            // why are you even doing this?
            try {
                Thread.sleep(30);
            }catch (InterruptedException e){}
    
            // do the rest of the long running things
            p.waitFor();
            return null;
        }
    };
    task.setOnSucceeded(event -> {
        // modify ui to show success
    });
    
    task.setOnFailed(event -> {
        // modify ui to show failure
    });
    ExecutorService pool = Executors.newFixedThreadPool(2);
    
    pool.submit(task);
    
    // add more tasks...
    
    // shutdown the pool not keep the jvm alive because of the pool
    pool.shutdown();
    

    【讨论】:

    • 我实际上正在阅读以下教程。 www3.ntu.edu.sg/home/ehchua/programming/java/… 关于如何解决无响应的用户界面。那篇文章中的第 7 节展示了如何使用 Callable 来做到这一点。作者使用 Thread.sleep() 将控制权返回给主线程。
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    相关资源
    最近更新 更多