如果线程尚未完成,则暂停进一步执行

时间:2019-03-20 08:57:30

标签: java

我编写了一个程序,该程序执行cmd命令并将输出打印到程序的“控制台”。我已经使用Thread打印输出而不冻结程序。我希望能够看到实时输出。

问题出在哪里,我找不到解决方案,因为在执行initialize方法之后,executeCommand中的一部分在executeCommand之后立即执行。我想要做的是一旦线程停止运行就执行其余的初始化。如果不冻结整个程序,我就做不到。

我使用了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();
        }
    }

}

1 个答案:

答案 0 :(得分:1)

如果要打印到控制台,请在成功执行(未执行)一个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之一来实现