【问题标题】:Thread-safe way to call an external process (and grab its output stream) from inside an EJB从 EJB 内部调用外部进程(并获取其输出流)的线程安全方式
【发布时间】:2014-02-13 03:51:17
【问题描述】:

如何从 EJB 内部以线程安全的方式调用外部进程?

ProcessBuilder 不是线程安全的,如 javadoc 中所述。 Apache commons exec 对线程安全只字未提,我对 Runtime.exec 也没有信心。

正确的方法是什么?

让我添加一些代码,这样人们就不会认为我在滥用,这段代码有时有效,有时无效

public int startTask(Logger logger, String expectPath, String expectScriptPath, long ticket) throws IOException {
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(expectPath+" "+expectScriptPath+" "+ticket);

    SessionLogger sysout = new SessionLogger(logger,p.getInputStream());
    sysout.start();

    SessionLogger syserr = new SessionLogger(logger,p.getErrorStream());
    syserr.start();

    try {
        return p.waitFor();
    } catch (InterruptedException e) {
        log.error(e.getMessage(),e);
        return -1;
    }

}

请不要关闭或否决这个问题。

我知道这不是线程安全的。我只是想知道如何从 EJB 中正确地做到这一点。

【问题讨论】:

    标签: java multithreading runtime.exec processbuilder apache-commons-exec


    【解决方案1】:

    EJB 的要点之一就是您不必担心并发性,您可以保证在任何给定时间只有一个线程会调用您的 EJB 方法。 ProcessBuilder 不必是线程安全的,只要您不将其设为静态,也不在 EJB 的不同实例之间共享相同的实例。

    【讨论】:

    • 感谢您的回答。好吧,我同意你的看法,这就是 EJB 的想法。但是在几个 MDB 中运行此代码后,我遇到了一些无法重现的奇怪错误,因此我的第一个怀疑是 Runtime.exec。你认为如果我从无状态 EJB 内部调用 ProcessBuilder,那么线程安全就足够了吗?
    • 实际上Runtime.exec 应该也能完成这项工作,你能发布你遇到的错误吗?
    • 这就是问题所在。不抛出异常。但是当 10 个从 JMS 队列消费的 MDB 启动时,每个 MDB 都是一个 runtime.exec,不知何故它会弄乱结果。让我尝试隔离问题以在此处发布。谢谢
    猜你喜欢
    • 2011-11-28
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    相关资源
    最近更新 更多