【问题标题】:Non-blocking thread that runs an external process运行外部进程的非阻塞线程
【发布时间】:2011-05-09 20:39:27
【问题描述】:

我创建了一个 Java GUI 应用程序,它充当许多低级外部进程的包装器。该实用程序按原样运行,但迫切需要一项重大改进。

我希望我的外部进程以非阻塞方式运行,这将允许我并行处理其他请求。简而言之,我希望能够在生成数据时处理来自外部进程的数据。但似乎我检查外部进程是否仍在运行的基本尝试正在阻塞。

以下是我的 ExternalProcess 课程的摘录。有关线程和阻塞的特定 Java 功能问题,请参阅内联 cmets。

public void Execute()
{
    System.out.println("Starting thread ...\n");
    Runner = new Thread(this, "ExternalProcessTest");
    Runner.run();
    System.out.println("Ending thread ...\n");
}

public void run() 
{
    System.out.println("In run method ...\n");  // Debug purposes only. 
        // Show that we are in the run loop.
    try
    {
        // Execute string command SomeCommand as background process ...
        Process = Runtime.getRuntime().exec(SomeCommand);
        while(IsRunning())
        {
            // External process generates file IO.  I want to process these
            // files inside this loop.  For the purpose of this demo I have
            // removed all file processing to eliminate it as the cause
            // of blocking.  THIS ROUTINE STILL BLOCKS!
            Thread.sleep(1000);
        }
    }
    catch(Exception e)
    {
        System.out.println(e);
    }
    System.out.println("Exiting run method ...\n");  // Debug purposes only.
        // Show that we are exiting the run loop.
}

// Process (instantiated from Runtime.getRuntime().execute doesn't supports
// either fire-and-forget backgrounding (non-blocking) or you can wait for 
// the process to finish using the waitFor() method (blocking).  I want to
// be able to execute a non-blocking external process that I monitor via
// threading allowing me to process the external process file IO as it is
// created.  To facilitate this goal, I have created an isRunning() method
// that uses the exitValue() method.  If the process is still running, a 
// call to exitValue() will throw an IllegalThreadStateException exception.
// So I simply catch this execption to test if the background process is
// finished -- at which point I can stop processing file IO from the 
// process.  Is this the source of the blocking?  If so, is there another
// way to do this?
public boolean IsRunning()
{
    boolean isRunning = false;
    try
    {
        int exitVal = Process.exitValue();
    }
    catch(IllegalThreadStateException e)
    {
        isRunning = true;
    }
    return isRunning;
}

【问题讨论】:

    标签: java multithreading nonblocking


    【解决方案1】:

    Thread 上的 run() 方法实际上并没有启动新线程,请尝试使用 Thread.start() 代替。

    【讨论】:

    • 哇。那是相当骨感。但你是对的。做到了。非常感谢迈克!
    • 我自己不止一次爱上了它。 :-)
    【解决方案2】:
    Runner = new Thread(this, "ExternalProcessTest");
    Runner.run();
    

    run() 方法具有欺骗性的名称。因为Thread 实现了Runnable 接口,所以run() 方法是公开的,但是不是当你想启动一个新线程时调用的正确方法。调用run() 会导致线程代码在当前线程中运行。

    您必须调用start() 来实例化一个新线程:

    Runner = new Thread(this, "ExternalProcessTest");
    Runner.start();
    

    【讨论】:

    • 谢谢约翰。做到了。感谢您抽出宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多