java - 从作为后台作业运行的 shell 脚本生成进程

标签 java multithreading shell

我正在开发一个 Web 应用程序,在前端运行 Java,在后端运行 shell 脚本。该应用程序主要是分析许多文件,java 程序从用户那里获取输入,例如他们想要分析哪个文件,从哪个日期到他们想要分析的哪个日期。让我们假设用户提供 7 月 1 日至 8 日的数据。我需要处理 8 天的文件。每天大约有 100 个文件需要处理。所以我的目标是使这个过程并行而不是顺序执行。对此我基本上有两个想法。我想与大家分享这个并获取你们的建议。

计划1: 有一个Java程序(业务层),它使用流程构建器调用shell脚本。我可以将用户给定的日期(例如(1-8))拆分为 4 个线程,每个线程将执行两天的操作。例如 (1-2) 线程 1 和 (3-4) 线程 2,然后继续。如果我遵循这种方法,有哪些优点和缺点?还有如何通过这种方法在线程之间进行协调。

计划2: 从 Java 调用 shell 脚本,并在 shell 脚本内部生成多个进程,正如我之前所说,我可以生成进程 1 来执行日期 (1-2) 和进程 2 (3-4) 的工作,然后继续。这种方法的优点和缺点是什么?我将处理后的输出写入一个文件中。因此,如果我有多个进程,如何使多个进程更新单个文件。

还有与我的问题相关的任何链接的引用

重要: 正如我所说,我需要在 shell 脚本中每天处理 100 个日志文件,我的要求之一是不断更新有关 shell 脚本中作业状态的前端环境(即第 1 天已完成,第 1 天) 2已完成等。我知道我可以从 shell 脚本中执行 echo,然后我可以从 Java 中获取值。但问题是,如果我在 shell 脚本内、处理文件的循环内执行 echo,我的调用就会终止,并且我必须再次从 Java 回调。关于如何进行此更新的任何想法。

最佳答案

首先,我建议考虑优化的第一条规则:不要优化。

然后,如果你真的认为需要优化它,我会选择第一种方法,并尽可能在 Java 中进行。

一种方法可能如下: 1) 使用 ProcessBuilder 运行所有进程并创建 List<Process> 2)将每个Process包装成一个ShellScriptProcess并获取List<ShellScriptProcess>

class ShellScriptProcess implements Runneable() {

  private Process process;
  public ShellScriptProcess(Process process) {
     this.process=process;
  }

  boolean synchronized finished = false;
  public void run() {
    process.waitFor(); //this will wait until the process terminates
    finished = true;
  }
  public boolean isFinished(){
    return finished;
 }
}

3)等待进程完成

while(!allFinished) {
    for (ShellScriptProcess sp : shellScriptProcesses) {
      allFinished = true;
      if (sp.isFinished()) {
          // hurray, a process has finished, inform the UI
          // you want to do something smarter here though, 
          //like removing the finished processes from the list
      }
      else {
          allFinished = false;
      }
   }
}

这只是一个非常粗略的解决方案,只是为了演示如何实现这一点。我没有测试代码,它可能包含语法错误:)希望这有帮助。

关于java - 从作为后台作业运行的 shell 脚本生成进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11544955/

相关文章:

java - 服务无法启动 : error 1067: the process terminated unexpectedly

java - Matlab Java 互操作性

java - 为什么我的解决方案对于反转整数是错误的?

java - 多线程Java小程序弹跳球

java - Request.getParameter() 仅将 "+"替换为 ""

java - android:定期在任务或线程中拍照?

c++ - 我们是否需要对只有 read 方法的类进行线程安全设计?

linux - 如何将参数传递给 erlang os :cmd()?

linux - 搜索特定字符串并在特定字符串之间打印——Linux Shell 脚本

linux - 使用 sed 和 pstree 显示正在使用的终端类型