如何从两个单独的JavaFX服务线程获得结果?

时间:2016-07-14 20:31:17

标签: java javafx concurrency

我是javaFx的新手,所以我可能会在这里找不到容易的东西,但我似乎无法找到这个解决方案。我有一个应用程序,需要并行执行两个单独的函数,然后只有当两者都返回返回值时才需要更新UI。我已经创建了一些测试代码,如下所示,除了结果之外,每个东西都有效。我怎样才能打印出线程执行的结果。在我的示例中,标签应显示为thread1Result: false thread2Result: true,但两者都显示为null。

主要课程

public class Main extends Application {
public static void main( String[] args ) {
    launch( args );
}

/* (non-Javadoc)
 * @see javafx.application.Application#start(javafx.stage.Stage)
 */
@Override
public void start( Stage primaryStage ) throws Exception {
    Parent root = FXMLLoader.load( getClass().getResource( "/application/LoadPage.fxml" ) );
    Scene scene = new Scene( root );
    scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.show();

}
}

LoadPage.fxml

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">

                 

ControllerClass

public class Controller {
@FXML Label lbl_Status;
Boolean thread1Result = null;
Boolean thread2Result = null;

public void doIt(ActionEvent event){
    Button doitButton = ((Button) event.getSource() );
    doitButton.setDisable( true );
    ExecutorService es = Executors.newFixedThreadPool(2);
    final ServiceExample service1 = new ServiceExample(4000);
    final ServiceExample service2 = new ServiceExample(5000);
    service1.setExecutor( es );
    service1.setOnSucceeded( new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle( WorkerStateEvent arg0 ) {
            thread1Result = service1.getValue();
        }
    });
    service2.setExecutor( es );
    service2.setOnSucceeded( new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle( WorkerStateEvent arg0 ) {
            thread2Result = service2.getValue();
        }
    });
    service1.start();
    service2.start();

    try {
        es.shutdown();
        es.awaitTermination( 2, TimeUnit.MINUTES );
    } catch ( InterruptedException e ) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    doitButton.setDisable( false );
    lbl_Status.setText( "thread1Result: " +  thread1Result + "  thread2Result: " + thread2Result );} }

ServiceExample Class

public class ServiceExample extends Service<Boolean> {
private int waitTime;
   public ServiceExample( int waitTime ) {
      this.waitTime = waitTime;
   }
   @Override
   protected Task<Boolean> createTask() {
       return new Task<Boolean>() {
        @Override
        protected Boolean call() throws Exception {
            Thread.sleep(waitTime);
            if(waitTime >= 5000){
                return true;
            }else{
                return false;
            }
        }
      };
     }}

提前致谢。

1 个答案:

答案 0 :(得分:3)

电话

es.awaitTermination( 2, TimeUnit.MINUTES );

是一个阻止调用,所以你不应该在FX应用程序线程上执行它,因为它会使UI无响应。

当服务的任务完成时,state的{​​{1}}属性将为Service。所以你可以做到以下几点:

SUCCEEDED