V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sandman511
V2EX  ›  Java

Java 调用 cmd:请教一下 process.waitFor()机制

  •  
  •   sandman511 · 2019-12-30 11:30:23 +08:00 · 3721 次点击
    这是一个创建于 1810 天前的主题,其中的信息可能已经有所发展或是发生改变。
            try {
                Runtime runtime = Runtime.getRuntime();
                Process process = runtime.exec(cmdPathName, null, new File(folderPathName));
                process.waitFor();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    这一段代码 runtime.exec()一句耗时 0.5 秒左右
    process.waitFor()一句耗时 0.7 秒左右 这是为什么呢?
    查阅了一下资料,说是调用 runtime.exec 会开启一个子进程执行 cmd,process.waitFor()是在等待子进程执行结束,这样理解正确吗?
    因为后续接口程序涉及到了多次调用,这样话( 0.5+0.7 ) X N 次,接口返回数据的时间很慢。
    请教一下,我该如何降低一下这( 0.5+0.7)秒?
    
    PS:markdown 中直接换行为什么不起作用。。。
    
    9 条回复    2020-01-05 15:53:56 +08:00
    lihongjie0209
        1
    lihongjie0209  
       2019-12-30 11:40:39 +08:00
    那你不用 Java, 直接调用 CMD 多长时间
    xiangyuecn
        2
    xiangyuecn  
       2019-12-30 11:47:39 +08:00
    0.5 秒无能为力,0.7 秒可以优化掉,直接开线程接收 stdout、stderr,不要结果那就直接不等结果,开定时器直接到时间 close 一遍清理掉
    sandman511
        3
    sandman511  
    OP
       2019-12-30 11:49:56 +08:00
    @lihongjie0209 小于 1 秒 目测 0.5-0.7 秒吧
    xuyang2
        4
    xuyang2  
       2019-12-30 11:54:06 +08:00
    你不去定位一下所创建进程的启动时间,实际任务的处理时间,
    一上来就怀疑是 jdk 创建进程,等待进程方法的额外开销吗?
    ipwx
        5
    ipwx  
       2019-12-30 12:05:47 +08:00
    开关进程本来就是开销大的操作。

    如果你有被调用程序的源代码,写个 RPC 呗。
    codehz
        6
    codehz  
       2019-12-30 13:31:04 +08:00
    其实有一半时间是 win 的锅(当然并不是说 win 很烂,只能说设计目标不一样)
    win 开进程就是要有一定的延迟(相比 linux/bsd 的 fork+exec
    你的这种思路,就类似传统 CGI 思路,当时在传统*nix 系统上还能拼出几百甚至几千并发,到了 win 上就是低了一个数量级,当然了,上了 FastCGI,就差别不大了(一定不是 php 的锅!)
    然后 FastCGI 才会顺利上位(
    zpf124
        7
    zpf124  
       2019-12-30 14:07:11 +08:00   ❤️ 1
    说个与主体内容无关的。

    markdown,默认一个换行就是不显示换行的。
    行尾加俩空格 才是显示出来的换行,相当于<br>
    两个换行,也就是空一行,代表段落分隔, 相当于<p>
    matepi
        8
    matepi  
       2019-12-30 17:31:50 +08:00
    同 2 楼,可以尝试一下套接输入输出流
    https://stackoverflow.com/questions/5483830/process-waitfor-never-returns
    还有,线尝试一下并行?或者写成个 bat 提高一定程度无等待的直接在操作系统中的串行?

    同时说个和主体内容有关的,当把输入输出流套接到 log4j 之类的之后,发现串行执行时 log4j 的日志会乱序,可能是 log4j 的异步机制导致,但也没有找到 log4j/slf4j 的 flush 方法。目前就是每次等待执行输出流完成后,sleep 了 3ms 来解决这个问题。有更优雅的 flush 日志的做法吗?
    SoloCompany
        9
    SoloCompany  
       2020-01-05 15:53:56 +08:00 via iPad
    如果进程执行顺序没有依赖,可以把 runtime 存到 list 里面,等所有进程都启动完了再循环执行 waitFor
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4538 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 03:51 · PVG 11:51 · LAX 19:51 · JFK 22:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.