简体   繁体   English

如何停止线程,以使在其上运行的任务永久停止?

[英]How can you stop a thread so that the task running on it stops permanentl?

I have a javafx application. 我有一个javafx应用程序。 I programmed it such that the application starts with a progress bar that runs to completion. 我对其进行了编程,以使应用程序从运行到完成的进度条开始。 On completion, The window closes and a login window opens. 完成后,该窗口关闭,并打开一个登录窗口。 After you sign in, the login window closes and the main window opens. 登录后,登录窗口关闭,主窗口打开。

But that is not what is happening in my application. 但这不是我的应用程序中发生的事情。

I made a task that runs the progressbar from 0 - 100 and I made the task to run on a Thread. 我做了一个从0-100运行进度条的任务,并且使该任务在线程上运行。 When the task is completed, the window closes and login window opens. 任务完成后,窗口关闭,并且登录窗口打开。

The problem I am encountering is that when I sign in using the login window, the main window opens but the login window didn't close. 我遇到的问题是,当我使用登录窗口登录时,主窗口打开,但登录窗口没有关闭。

I wrote a method to close the login window when the main window opens, but That didnt work. 我编写了一种在主窗口打开时关闭登录窗口的方法,但是没有用。

Please what am I missing? 请我缺少什么?

This is the task class 这是任务班

public class TaskClass implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                progress.setProgress(i / 100.0);
                Thread.sleep(100);

            } catch (InterruptedException ex) {
                Logger.getLogger(RunningController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                // this is the method that closes the  window on which the progress bar is running
                closed(clos);  
                // this is the method that opens the login
                windowloadwindow("/inventory/management/login/InventoryManagementlogin.fxml", "DeMak Inventory");
            }
        });
    }
}

This loads the progress bar on a thread 这将进度条加载到线程上

Thread thread;

@FXML
private JFXProgressBar progress; 

@Override
public void initialize(URL url, ResourceBundle rb) {
    progress.setProgress(0.0);
    Runnable tasks = new TaskClass();
    thread = new Thread(tasks);
    thread.start();
}

After you must have signed in using the login window, This is meant to happen 在您必须使用登录窗口登录后,这将发生

loadwindow("/inventory/management/ui/Main/main.fxml", "Deemax   Inventory");  // a method that opens the main window  

closed(closew);     // a method that closes the login window

In order to synchronize Platform.runLater() code and background thread code you could use the CountDownLatch Class as following: 为了同步Platform.runLater()代码和后台线程代码,可以使用CountDownLatch类,如下所示:

Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                CountDownLatch sync = new CountDownLatch(1);  
                Platform.runLater(()->{
                    // GUI code
                    // ...
                    // end of GUI code
                    sync.countDown();
                });
                sync.await(); // This method will wait for sync.countDown() to be executed 
                // ...
                // code here will be executed after GUI code has finished
                // ...
                return null;
            }
        };
        Thread thread = new Thread(task);
        thread.start(); 

But , instead you can solve your problem much easier like this: 但是 ,相反,您可以像这样更轻松地解决问题:

Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            for (int i = 0; i < 100; i++) {
                final int finalCounter = i;
                Platform.runLater(()->{
                    try {
                        progress.setProgress(finalCounter / 100.0);
                    } catch (InterruptedException e) {
                        Logger.getLogger(RunningController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                });
                Thread.sleep(100);
            }
            return null;
        }
        @Override
        protected void succeeded() {
            // code here will be executed after the thread had been completed
            Platform.runLater(()->{
                new Alert(Alert.AlertType.INFORMATION, "Thread Succeeded!").show();
            });
            closed(clos);      // this is the method that closes the  window on which the progress bar is running
            loadwindow("/inventory/management/login/InventoryManagementlogin.fxml", "DeMak Inventory");     // this is the method that opens the login window
            super.succeeded();
        }
        @Override
        protected void failed() {
            Platform.runLater(()->{
                new Alert(Alert.AlertType.ERROR, "Thread Failed!").show();
            });
            super.failed();
        }
    };
    Thread thread = new Thread(task);
    thread.start();

This is my closed method 这是我的封闭方法

         private void closed(Node nor) {
        Stage stage = (Stage)nor.getScene().getWindow();
        stage.close();
        }

This is my node object.... It is a vbox containing an X image 这是我的节点对象。...这是一个包含X图像的vbox

  @FXML
private VBox clos;

so I pass the node to the method like this. 所以我将节点传递给这样的方法。

closed(clos);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM