我的程序中有多个线程(runnables)。主题是处理RS232通信。 我的问题是循环中的代码没有按照写入的顺序执行:
while(!serialData.dataToSend.isEmpty())
{
try {
SerialMsgToSend msgObject = serialData.dataToSend.remove();
if(msgObject.type == msgObject.HOLDING_REGISTER)
{
Thread.sleep(COMMAND_WAIT_TIME);
Toolkit.getDefaultToolkit().beep();
modBusManager.singleRegisterWriteToMultipleRegisters(msgObject.unit, msgObject.startRegisterAdress, msgObject.data);
}
else if(msgObject.type == msgObject.COIL)
{
Thread.sleep(COMMAND_WAIT_TIME);
Toolkit.getDefaultToolkit().beep();
modBusManager.writeToCoil(msgObject.unit, msgObject.startRegisterAdress, msgObject.data[0] == 1);
}
Thread.sleep(5000);
readUnitsData(msgObject.unit);
Thread.sleep(5000);
if(msgObject.RESPONSE > 0)
{
serialData.listeners[msgObject.unit - 1].sendResponseToServer(msgObject.RESPONSE);
}
} catch (Exception ex) {
log.error("Exception on sending data: " + ex.toString());
}
}
首先,我通过调用
写入ModBus寄存器modBusManager.singleRegisterWriteToMultipleRegisters(msgObject.unit, msgObject.startRegisterAdress, msgObject.data);
之后我想等待5秒钟更新寄存器,然后读取它们并将信息发送到服务器。
我用调用方法读取数据:
readUnitsData(msgObject.unit);
然后我使用监听器告诉另一个线程将数据发送到服务器:
serialData.listeners[msgObject.unit - 1].sendResponseToServer(msgObject.RESPONSE);
我的问题是数据在被读取/更新之前被发送到服务器,因此我发送旧数据。我用的是代码按写入的顺序执行。我是以错误的方式使用线程还是可能出现问题?
这是我打电话来读取数据的方法:
private void readUnitsData(int unitID)
{
if(mtxData.climatList[unitID] != null)
{
try
{
log.info("Serial reading data for: " + unitID);
int[] coils = modBusManager.readCoils(unitID + 1,0,87);
String[] holding = modBusManager.readHoldingRegisters(unitID + 1,0,64); //(int slaveAdress, int registerAdress, int registerQuntaity)
if(coils != null && holding != null)
{
System.out.println("send to listner: " + unitID);
serialData.listeners[unitID].newHoldingAndCoilData(holding, coils);
}
} catch (Exception ex)
{
log.error("Exception on run: " + ex.toString());
}
}
}
其他runnable中的方法,它连接到监听器:
@Override
public void sendResponseToServer(int responseType)
{
try
{
log.info("listener for sendStatusToServer called: " + responseType);
Thread.sleep(15000);
switch(responseType)
{
case 1:
communicationManager.sendStatus();
break;
case 2:
communicationManager.sendSettings();
break;
}
}catch(Exception ex)
{
log.error("Exception on sendResponseToServer: " + ex);
}
}
答案 0 :(得分:1)
我确实喜欢@Markus Mitterauer提议并拆开了代码。我发现其中一个unitID是错误的。因此,在读取寄存器时我没有获得任何值,并且没有正确触发听众。