2016-08-22 6 views
0

У меня есть несколько потоков (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()); 
     } 
    } 
} 

И метод внутри другого работоспособной, который подключен к слушателю:

@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

От отправленного кода я не вижу причин, почему это не должно выполняться в письменном порядке. За исключением появления «Исключения». Вы уверены, что ни один из ваших других потоков не закаляет ваши объекты коммуникации? –

+0

@MarkusMitterauer У меня есть только один поток, который начинает писать/читать сообщения в ModBus. Для меня это похоже на тот поток, который обрабатывает RS232, всегда ждет, когда слушатель завершит работу до вызова readUnitsData(). Поскольку я добавил увеличенный Thread.sleep (15000) к большему числу, и с этим увеличилось время readUnitsData(). Можно ли использовать runnables и прослушиватели так, как я их использую, или что может быть проблемой? – Jure

+0

Ну, боюсь, я не знаю другого совета, кроме как попробовать [отладить] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) вашу программу и посмотреть, что на самом деле происходит. - Как я уже сказал, я не вижу проблем в коде, который вы предоставили, но многопоточность является сложной темой, и в коде, который вы запускаете в других потоках, могут быть еще ловушки. Возьмите это приложение. Выполните только один поток. (удаленный) отладить его и/или добавить больше логических операторов. Поймите, что происходит. –

ответ

1

Я сделал, как @Markus Mitterauer предложил и разобрали код. Я обнаружил, что это проблема с одним из идентификаторов unitID, который был неправильным. Из-за этого я не получал никаких значений при чтении регистров, и слушатель не запускался правильно.

+0

Отлично. Затем просто отметьте это как * ответ * на свой вопрос. –