2013-04-16 9 views
10

Jestem nowy z JavaFX i mam mały problem z wątkiem: mogę go wykonać dwa razy i nie mogę znaleźć przyczyny.JavaFX: Użyj wątku więcej niż raz

Oto sumy uPT mojego kodu:

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

Kiedy klikam raz pierwszy przycisk, który rozpocznie mój wątek, mój bieg zadanie bez problemu (mój wyświetlacz konsola „GO!” I " SUCCEEDED ").

Ale jeśli kliknę drugi raz, nic nie będzie dołączane. Czy robię coś źle ? Czy nie możemy użyć nici więcej niż raz?

+1

Nie, nie możesz użyć wątek więcej niż jeden raz. – xagyg

Odpowiedz

11

Z dokumentacji Thread.start(): nr

Nigdy nie jest legalny, aby rozpocząć wątek więcej niż jeden raz. W szczególności wątek nie może zostać uruchomiony ponownie po zakończeniu wykonywania.

z samouczka Concurrency in JavaFX:

Klasa Zadanie definiuje przedmiot jednorazowego, które nie mogą być ponownie wykorzystane. Jeśli potrzebujesz potrzebnego do ponownego użycia obiektu Worker, użyj klasy Service.

Musisz więc wziąć pod uwagę klasę Service, a nie Task.


Edit: ten powinien pracować dla Ciebie:

Service<Void> service = new Service<>(task); 

@FXML protected void launch(ActionEvent event){ 
    if (!service.isRunning()) { 
     service.reset(); 
     service.start(); 
    } 
} 
+0

Dziękuję bardzo za pomoc. Poszukuję tego teraz :) – SylCh

+0

Pamiętaj, aby samemu ustawić executor i użyć go ponownie, lub wciąż tworzysz nowe wątki. –

+0

@AndyCzy możesz zaproponować lepsze podejście? – tarrsalah

0

Zrób to z klasą 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); 
          } 
       } 
      } 
+0

w jaki sposób Twój kod pomaga w odpowiedzi na pytanie? –

+1

Możesz uruchomić zadanie tyle razy, ile chcesz –

1

z przyciskiem może wystrzelić nowych zadań

    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..."); 
         } 
        }); 
Powiązane problemy