10

我是 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”)。

但是,如果我再次单击,则不会有任何附加内容。难道我做错了什么 ?我们不能多次使用线程吗?

4

3 回答 3

11

来自 Thread.start() 文档:

多次启动一个线程是不合法的。特别是,线程一旦完成执行就可能不会重新启动。

来自JavaFX 中的并发教程:

Task 类定义了一个不能重复使用的一次性对象。如果您需要一个可重用的 Worker 对象,请使用 Service 类。

因此,您必须考虑Service类而不是Task


编辑:这应该适合你:

服务服务=新服务<>(任务);

//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 回答