在 comport 上等待输入的 java 线程也会阻止其他线程

java thread waiting for input on comport blocks other thread as well

提问人:JeroenV 提问时间:11/5/2013 最后编辑:JeroenV 更新时间:11/5/2013 访问量:552

问:

我有一个启动两个线程的主程序。首先我只有这个线程,它在 while(true) 中执行以下内容:

loopCounter++;              
outputStream.write(pollBuf);
readResponse();
Thread.sleep(200);
outputStream.write(statusBuf);
readResponse();
logger.info("status executed");

问题是,当第二个 readResponse 没有返回时,因为监听 comport 的设备根本没有回答,我被卡住了,并且给出机器状态的显示屏仍然显示“正在运行”,而不是软件错误或类似的东西。 所以我需要知道这个线程何时被卡住,因此我添加了另一个线程,该线程现在在另一个线程之前在主程序中创建并启动,这是第二个线程的 run() 方法的 while(true) 中的代码:

public class StatusThread implements Runnable {
  static Logger logger = Logger.getLogger(StatusThread.class);

  private Nv10ToVcdm mainProgram;

  public void initialize(Nv10ToVcdm mProgram, boolean acceptBills) {
    mainProgram = mProgram;
  }

  public void run() {
    int loopCounter = mainProgram.getLoopCounter();
    while (true) {
      try {
        Thread.sleep(1000);
        int currentLoopCounter = mainProgram.getLoopCounter();
        if (loopCounter != currentLoopCounter) {
          loopCounter = currentLoopCounter;
        } else {
          mainProgram.writeToDisplay("SOFTWARE", "ERROR");
        }
      } catch (InterruptedException ie) {
        logger.error("Interrupted exception: " + ie.getMessage());
        mainProgram.errorOnDisplay();
      }
    }
  }
}

可悲的是,第一个线程卡在侦听 comport 时并没有释放它在 cpu 上的声明,因此第二个线程没有获得任何 CPU 时间。那么:当监听com端口的线程挂起时,如何在显示屏上显示错误?

挂起的 readResponse 方法,因为它挂在“byte firstByte = (byte) inputStream.read();” 上,因为没有什么可读的:

private void readResponse() {
    byte[] bufferLeft = new byte[4];
    byte[] bufferRight = new byte[2];
    byte size = 0;
    boolean responseFound = false;

    try {
      while(!responseFound) {
        byte firstByte = (byte) inputStream.read();
        if (firstByte == -1) {
          logger.error("first byte of response is -1");
          mainProgram.errorOnDisplay();
          break;
        }
        for (int i = 0; i < 4; i++) {
          bufferLeft[i] = (byte) inputStream.read();
        }
        size = bufferLeft[0];
        if (size > 0) {
          bufferRight =  new byte[size];
          int i2 = 0;
          while (i2 < size) {
            bufferRight[i2] = (byte) inputStream.read();
            i2++;
          }
        }

        if (firstByte == 1 && bufferLeft[1] == 40) {
          responseFound = true;
        }
      }

      if (size == 11) {
        // some code
      }
    } catch(IOException ioe) {
      logger.error("IO Exception in readResponse: " + ioe.getMessage());
      mainProgram.errorOnDisplay();
    }
}

编辑(为第二个线程和readResponse方法添加了完整的代码)

Inputstream 的初始化方式如下:

serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
inputStream = serialPort.getInputStream(); 
Java 多线程

评论

0赞 MadConan 11/5/2013
您需要为此显示所有代码。什么是线程共享?
0赞 azz 11/5/2013
我们真的需要代码来提供帮助。readResponse()
0赞 Gray 11/5/2013
如果线程被阻塞,那么它肯定会“释放它在 cpu 上的声明”。即使它正在旋转,另一个线程也应该得到一些循环。我怀疑这两个线程都被阻止了。
0赞 dcsohl 11/5/2013
您确定有数据要读取吗? 将阻止,直到有数据。inputStream.read()
0赞 Taylor 11/5/2013
stackoverflow.com/questions/804951/......可能会有所帮助

答:

1赞 Alexey Sidelnikov 11/5/2013 #1

在读取之前,您是否尝试过欺骗数据可用性?

像这样:

if (inputStream.available() > 0) {
  // do your read
} else {
  // wait for some time and retry or trow an error
}