【问题标题】:Run Method in the Thread class not being called未调用 Thread 类中的 Run 方法
【发布时间】:2011-03-28 09:59:50
【问题描述】:

我是线程领域的新手,已经尝试解决这个问题一周了。

由于某种原因没有调用 Thread 类中的 run 方法,我不知道为什么(但很想知道)

        ProcessBuilder processBuilder = new ProcessBuilder();

        processBuilder.command("/bin/sh", "-c", "echo \"w30000001z,none,16488,,181075\nw30000001z,none,16488,,181082\n\" | /home/beehive/bin/exec/tableSize");
        Process process = processBuilder.start();
        process.waitFor(); 

        InputStream stdin = process.getInputStream();
        OutputStream stdout = process.getOutputStream();
        InputStream stderr = process.getErrorStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
        BufferedReader error = new BufferedReader(new InputStreamReader(stderr));
        StreamGobbler errorStream = new StreamGobbler(process.getErrorStream(), "ERROR");
        StreamGobbler outputStream = new StreamGobbler(process.getInputStream(), "OUTPUT");

        errorStream.start();
        outputStream.start();
        errorStream.join();
        outputStream.join();

tableSize 是一个 python 可执行文件,它通过它的标准输入接受输入,处理它并输出几行文本。我需要收集此输出并对其进行进一步处理。

有一个单独的线程来处理 inputStream 和 errorStream 上的输出。这个线程类如下图。

/* StreamGobbler.java */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

class StreamGobbler extends Thread
{
    InputStream is;
    String type;
    OutputStream os;

    StreamGobbler(InputStream is, String type)
    {
        this(is, type, null);

    }
    StreamGobbler(InputStream is, String type, OutputStream redirect)
    {
        this.is = is;
        this.type = type;
        this.os = redirect;
    }

    public void run()
    {
        try
        {
            PrintWriter pw = null;
            if (os != null)
                pw = new PrintWriter(os);

            System.out.println("Ajay" + type);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
            {
                if (pw != null)
                    pw.println(line);
                System.out.println(type + ">" + line);    
            }
            if (pw != null)
                pw.flush();
        } catch (IOException ioe)
            {
            ioe.printStackTrace();  
            }
    }
}

由于某种原因,StreamGobbler 类中的 run 方法没有被调用。但是这个类的构造函数正在执行中。

任何帮助将不胜感激。

【问题讨论】:

  • 我会删除 BufferedReaders。他们似乎没有任何好处。

标签: java multithreading iostream processbuilder


【解决方案1】:

您需要在调用process.waitFor() 之前启动流吞噬者。

流吞噬者读取并丢弃外部进程输出/错误流,以便外部进程在尝试写入时不会阻塞。但是按照您的方式,该过程必须在您尝试吞噬输出之前完成写入(并退出)。

结果 - 死锁...如果外部进程对其输出流写入过多。


实际上,我认为主要 问题是您的Java 代码没有向inputStream 写入任何内容。因此,外部进程只是坐在那里等待永远不会到达的输入......而process.waitFor() 等待外部进程。死锁。

事情的正确顺序应该是:

  1. 构建流程并启动它。
  2. 构建 gobblers 并启动它们。
  3. 打开输入流。
  4. 将内容写入输入流。
  5. 关闭输入流。
  6. 调用process.waitFor() 并检查进程返回码。
  7. 查看 gobblers 捕获的输出

【讨论】:

  • 如果有帮助,java 代码不会挂起。它正常退出(没有任何异常),但不执行 run 方法。
  • @Paulo:我尝试在启动 gobblers 后调用 process.waitFor(),正如 Stephen 之前建议的那样。
  • @coderrookie - 您是否尝试根据我更新的答案修复程序?如果这不起作用,请在 gobblers 上调用 start 的行之前和之后添加跟踪图。
【解决方案2】:

您需要在Process.waitFor() 之前使用STDOUT 和/或STDERR,这是一篇很棒的文章: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2

【讨论】:

    【解决方案3】:

    1) 如果不需要,请尝试删除 waitFor()。它只是让正在执行的线程等待,直到进程执行完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 2012-06-15
      • 1970-01-01
      • 2012-10-06
      • 1970-01-01
      • 2020-11-29
      相关资源
      最近更新 更多