我正在开发一个 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/