如何在方法完成之前继续循环?

时间:2016-08-22 13:16:02

标签: java multithreading listener runnable

我的程序中有多个线程(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);
    }
}

1 个答案:

答案 0 :(得分:1)

我确实喜欢@Markus Mitterauer提议并拆开了代码。我发现其中一个unitID是错误的。因此,在读取寄存器时我没有获得任何值,并且没有正确触发听众。