JavaFX: использование потока более одного раза
Я новичок в JavaFX, и у меня небольшая проблема с потоком: я могу выполнить его дважды, и я не могу найти почему.
Вот сумма моего кода:
Task<Void> task = new Task<Void>() {
@Override public Void call() throws ImageLoadedException, HomographyException, IOException {
try{
System.out.println("GO !");
return null;
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void succeeded() {
super.succeeded();
System.out.println("SUCCEEDED");
}
};
@FXML protected void launch(ActionEvent event){
new Thread(task).start();
}
Когда я впервые нажимаю кнопку, которая запускает мой поток, моя задача запускается без каких-либо проблем (мой консольный дисплей "GO!" и "SUCCEEDED" ).
Но если я нажму второй раз, ничего не добавлю. Я делаю что-то неправильно? Не можем ли мы использовать поток более одного раза?
Ответы
Ответ 1
В документации Thread.start(): Нет
Невозможно запустить поток более одного раза. В частности, нить не может быть перезапущена после завершения выполнения.
Из Concurrency в JavaFX:
Класс Task определяет одноразовый объект, который нельзя использовать повторно. если ты нужен объект многократного использования, используйте класс службы.
Итак, вы должны рассмотреть класс Service, а не Task.
Изменить: это должно работать для вас:
Service<Void> service = new Service<>(task);
@FXML protected void launch(ActionEvent event){
if (!service.isRunning()) {
service.reset();
service.start();
}
}
Ответ 2
С помощью кнопки можно запускать новые задачи
Button btn = new Button();
btn.setText("New task");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
Executor ex=new Executor("Task"+count);
ex.start();
count++;
System.out.println("Task Starting...");
}
});
Ответ 3
Сделайте это с помощью класса wraper
import java.io.IOException;
import javafx.concurrent.Task;
public class Executor {
private String name;
private Task<Void> task;
public Executor(final String name) {
this.name=name;
task = new Task<Void>() {
@Override
public Void call() throws IOException, InterruptedException {
try {
int i=0;
while(i<20){
System.out.println(name);
Thread.sleep(2000);
i++;
}
return null;
} catch (IllegalThreadStateException e) {
System.out.println(e);
}
return null;
}
@Override
protected void succeeded() {
super.succeeded();
try {
System.out.println(name+" finish");
} catch (Exception ex) {
System.out.println(ex);
}
}
};
}
public void start() {
try {
Thread th = new Thread(task);
th.start();
} catch (Exception ex) {
System.out.println(ex);
}
}
}