如何在Java中同步运行进程?

3

我目前正在构建一个小型的swing应用程序,用于格式化驱动器、更改权限以及执行一些其他小任务。

目前,我遇到了一个问题,运行多个进程会导致它们异步运行,这很棒,因为它可以让我快速调度大量进程,但是对于我正在做的事情来说,我需要进程等待前面的进程完成。

我遇到的问题是,process.waitFor()方法会延迟GUI(swing)无法执行任何操作,直到所有进程完成。

我目前正在使用以下代码结构(我从这里实现的答案中获得)来部署我的命令/进程。

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

class RunSynchronously{
    private static final String sudoPassword = "1234";

    public static void main(String[] args) {
        Process process = null;
        String[] firstCmd = {"/bin/bash", "-c", "echo " + sudoPassword + "| sudo -S chmod 777 -R /media/myuser/mydrive"};
        try {
            process = Runtime.getRuntime().exec(firstCmd);
        } catch (IOException ex) {
            Logger.getLogger(Wizard_Home.class.getName()).log(Level.SEVERE, null, ex);
        }

        try {
            process.waitFor();
        } catch (InterruptedException ex) {
            Logger.getLogger(Wizard_Format.class.getName()).log(Level.SEVERE, null, ex);
        }

        String[] secondCmd = {"/bin/bash", "-c", "echo " + sudoPassword + "| sudo -S chmod 755 -R /media/myuser/mydrive"};
        try {
            process = Runtime.getRuntime().exec(secondCmd);
        } catch (IOException ex) {
            Logger.getLogger(Wizard_Home.class.getName()).log(Level.SEVERE, null, ex);
        }

        try {
            process.waitFor();
        } catch (InterruptedException ex) {
            Logger.getLogger(Wizard_Format.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

如何在保持GUI活跃而不休眠/等待的情况下延迟进程或创建队列?
2个回答

4
我怎样才能推迟处理或创建队列,同时保持我的GUI处于活跃状态而不是睡眠/等待状态?
使用SwingWorker,使处理在单独的线程中执行。
阅读 Swing 教程中关于 并发性 的部分,以获取更多信息和可工作示例。

谢谢您的建议,我会在周末查看那些教程并尝试一下,看看是否有助于我的情况 :) - Tyler

3
ExecutorService executor = Executors.newSingleThreadExecutor();
...
executor.execute(() -> yourLongRunningMethod());

思路是创建一个使用不同线程执行的executor,并在该线程中执行重型任务。在我的例子中,使用了单线程executor。这将使你的GUI线程只需要花费最少的时间(任务入队速度很快)。
请注意,使用此方法,你将至少有两个线程:GUI线程和executor线程。它们可能需要以某种方式进行通信(例如,在GUI中显示工作结果),因此它们可能需要修改一些共享数据。在这里,你可能需要一些同步(由于并发)。

谢谢您的建议,我会在这个周末更深入地研究您推荐的内容,看看是否有助于解决我的问题 :) - Tyler
1
例如,在GUI中显示工作结果(for example, to display work results in the GUI)时,您应该使用SwingWorker。 SwingWorker具有API,允许您“发布”结果或在任务完成时执行代码。此代码将在EDT上执行。 - camickr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接