簡體   English   中英

如果線程尚未完成,則暫停進一步執行

[英]Pause further execution if Thread has not finished

我編寫了一個程序,該程序執行一個cmd命令並將輸出打印到該程序的“控制台”中。 我已經使用Thread打印輸出而不凍結程序。 我希望能夠看到實時輸出。

它有什么問題,我找不到解決方案,因為executeCommand方法執行后立即執行了initialize ,而executeCommand方法被調用后立即進行了initialize 我想要做的是一旦線程停止運行就執行其余的初始化。 我不能不凍結整個程序而這樣做。

我使用了Thread join方法和類似方法,但是我的應用程序完全死機了。

這是我的主班

private String genCmd2;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                ConvertGUI window = new ConvertGUI();
                window.frmConvert.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public ConvertGUI() {
    initialize();
}

private void initialize() {
     // Execute a generated command concurrently
    genCmd2 = "ping google.com -n 5";
    executeCommand(genCmd2, genCmdTextArea);

    //CODE TO RUN AFTER EXECUTE COMMAND IS FULLY FINISHED
    //NOT RIGHT AFTER executeCommand method is called

}

public static void printToTheConsole(JTextArea console, String message) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            console.append(message);
            console.validate();
        }
    });
}

private static void executeCommand(String command, JTextArea console) {
    Runnable r = new CommandLineRunnable(command, console);
    t = new Thread(r);
    t.start();
}

我的Runnable類,它執行命令並將內容打印到控制台

public class CommandLineRunnable extends ConvertGUI implements Runnable {
    private String generatedCommand;
    private JTextArea console;

    public CommandLineRunnable(String command, JTextArea console) {
        this.generatedCommand = command;
        this.console = console;
        printToTheConsole(console, command);
    }

    @Override
    public void run() {
        StringBuilder output = new StringBuilder();
        BufferedReader reader;
        Process process;
        try {
            process = Runtime.getRuntime().exec(generatedCommand);
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;

            while ((line = reader.readLine()) != null) {
                output.append(line + "\n");
                printToTheConsole(console, line + "\n");
            }

            printToTheConsole(console, "\n--------------------------Success!--------------------------\n");

            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

如果要打印到控制台,請在(未)成功執行一個Runnable#任務期間和之后更新JTextArea,可以實現一個接口並將其提供給Runnables構造函數

考慮以下示例,該示例以參數String'aCommand'作為命令,fa JTextArea對象'console'和一個新的ResponseEvent匿名類作為參數實例化CommandLineRunnable類。

請注意,由於匿名類中的重復項,如果您要執行多個命令,則可能不想多次實例化匿名類,而只需在函數接口的方法內部插入printToTheConsole代碼即可。

    public static void main(String[] args) {

        JTextArea console = new JTextArea();

        /**
         * JTextArea init code here
         */

        executeCommand("aCommand", console, new ResponseEvent() {

            @Override
            public void onSuccess(JTextArea console, String response) {
                printToTheConsole(console, response);
            }

            @Override
            public void onUpdate(JTextArea console, String response) {
                printToTheConsole(console, response);
            }

            @Override
            public void onFailure(JTextArea console, String response) {
                printToTheConsole(console, response);
            }
        });
    }

    private static void printToTheConsole(JTextArea console, String message) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                console.append(message);
                console.validate();
            }
        });
    }

    private static void executeCommand(String command, JTextArea console, ResponseEvent event) {
        Runnable r = new CommandLineRunnable(command, console, event);
        Thread thread = new Thread(r);
        thread.start();
    }

    @FunctionalInterface
    private interface ResponseEvent {
        default void onSuccess(JTextArea console, String response) {

        }

        default void onUpdate(JTextArea console, String response) {

        }

        default void onFailure(JTextArea console, String response) {

        }

    }

    public static class CommandLineRunnable implements Runnable {

        private final String command;
        private final ResponseEvent event;
        private final JTextArea console;

        public CommandLineRunnable(String command, JTextArea console, ResponseEvent event) {
            this.command = command;
            this.console = console;
            this.event = event;
        }

        public ResponseEvent getEvent() {
            return event;
        }

        @Override
        public void run() {
            Process process;
            BufferedReader reader = null;
            try {
                process = Runtime.getRuntime().exec(getCommand());
                reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

                String line;

                while ((line = reader.readLine()) != null) {
                    getEvent().onUpdate(getConsole(), line + "\n");
                }

                getEvent().onSuccess(getConsole(), "\n--------------------------Success!--------------------------\n");
            } catch (IOException e) {
                getEvent().onFailure(getConsole(), "\n--------------------------Failure!--------------------------\n");
            }
        }

        private JTextArea getConsole() {
            return console;
        }

        private String getCommand() {
            return command;
        }
    }

執行后(可能在任何時間),將執行Runnable#run()函數。

代碼將運行,並且將調用ResponseEvent#onSuccess方法或ResponseEvent#onFailure方法

然后,您可以根據需要處理響應,也許可以通過更新JTextAreas之一來處理

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM