2016-11-26 8 views
0

Я пытаюсь получить гибкий графический интерфейс JavaFX при выполнении команды cmd.
Команда, которую я выполняю, следующая.Многопоточность с использованием Callable при наличии гибкого графического интерфейса

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

Как вы видите, что это YouTube-загрузчик, который преобразует ссылку на канал в mp3-файл. Я хочу, чтобы это выполнялось во втором потоке, а не в основном потоке FX.

Я решил это, реализовав интерфейс Callable в классе StartDownloadingThread.

@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(); 

Как мне сделать мой GUI реагировать с помощью интерфейса Callable?

ответ

0

Использование исполнителя для запуска задачи только для вас, используя метод getFuture, который возвращается при отправке задачи, фактически не освобождает исходный поток для продолжения других задач. Позже вы даже используете метод 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(); 
+0

Я действительно читал следующий учебник. https://www3.ntu.edu.sg/home/ehchua/programming/java/j5e_multithreading.html#zz-7.5 О том, как решить Бесполезный пользовательский интерфейс. В разделе 7 этой статьи показано, как вы можете это сделать, используя Callable. Писатель использует Thread.sleep() для возврата в основной поток. – Mnemonics

Смежные вопросы