10

私はJavaFXを初めて使用し、スレッドに少し問題があります.2回実行できますが、その理由がわかりません.

これが私のコードの要約です:

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」が表示されます)。

しかし、もう一度クリックしても何も追加されません。私は何か間違っていますか?スレッドを複数回使用することはできませんか?

4

3 に答える 3

11

Thread.start()ドキュメントから :いいえ

スレッドを複数回開始することは決して合法ではありません。特に、実行が完了すると、スレッドは再開されない場合があります。

Concurrency in JavaFXチュートリアルから:

Task クラスは、再利用できない 1 回限りのオブジェクトを定義します。再利用可能な Worker オブジェクトが必要な場合は、Service クラスを使用します。

したがって、TaskではなくServiceクラスを考慮する必要があります。


編集:これはあなたのために働くはずです:

Service service = new Service<>(タスク);

//Updated use this to create a new Service object instead
    Service service = new Service() {
    @Override
    protected Task createTask() {
        return new Task() {
            @Override
            protected Void call() throws Exception {
                //Your codes here
                return null;
            }
        };
    }
};

@FXML protected void launch(ActionEvent event){
     if (!service.isRunning()) {
        service.reset();
        service.start();
    }
}
于 2013-04-16T13:13:49.523 に答える
1

ボタンで新しいタスクを起動できます

                    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...");
                        }
                    });
于 2013-04-29T21:17:19.593 に答える
0

ラッパークラスでそれを行う

            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);
                            }
                }
            }
于 2013-04-29T21:14:14.130 に答える