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

标签 java multithreading

我有一个启动两个线程的主程序。首先,我只有这个线程,它在 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(); 

最佳答案

您在阅读之前是否尝试过检查数据可用性?

类似于:

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

关于java线程等待comport上的输入也会阻塞其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19790540/

相关文章:

Java 8 默认方法覆盖(和 eclipse)

multithreading - 尝试重新定义 IO::Tee::PRINT 以确保线程安全

java - 在java中隧道化两个套接字客户端

java - (Hadoop) : reduce method is not getting executed/called while running mapreduce job

java - 立方曲线JavaFX

java - 我可以使用根相对 XPath 表达式来获取克隆节点中的节点吗?

.net - 定期迭代不断变化的集合

java - 一次提交多个相关任务的线程池的推荐大小

c++ - 使用 shared_ptr 时出现 SEGFAULT

java - 比较打印文本中java中某些事件之前和之后的对象