2 つのスレッドを開始するメイン プログラムがあります。最初に、while(true) 内で次を実行するこのスレッドしかありませんでした。
loopCounter++;
outputStream.write(pollBuf);
readResponse();
Thread.sleep(200);
outputStream.write(statusBuf);
readResponse();
logger.info("status executed");
問題は、comport をリッスンしているデバイスが単に応答しないために 2 番目の readResponse が返されない場合、スタックしてしまい、マシンのステータスを示すディスプレイに、ソフトウェア エラーなどではなく「実行中」と表示されることです。似ています。したがって、このスレッドがいつスタックするかを知る必要があるため、別のスレッドを追加しました。このスレッドは、メイン プログラムで作成され、他のスレッドの直前に開始されます。この 2 番目のスレッドの 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 に対する要求を解放しないため、2 番目のスレッドは 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();
}
}
編集 (2 番目のスレッドと readResponse メソッドの完全なコードを追加)
入力ストリームは次のように初期化されます。
serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
inputStream = serialPort.getInputStream();