使用可调用的多线程,同时具有响应式图形界面



我正在尝试在执行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 响应?

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

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

此外,请确保在完成提交任务后关闭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();

相关内容

  • 没有找到相关文章

最新更新