2016-08-22 3 views
0

私のプログラムには複数のスレッド(runnables)があります。テーマは、RS232通信を扱うことです。メソッドが終了する前にどのようにループを継続できますか?

modBusManager.singleRegisterWriteToMultipleRegisters(msgObject.unit, msgObject.startRegisterAdress, msgObject.data); 

を私は5秒を待ちたいその後:呼び出すと

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レジスタに書き込む:ループ内のそのコードが書かれている順に実行されていない 私の問題がされそのレジスタは更新され、それらを読んで情報をサーバに送信します。

私が呼び出すメソッドを使用してデータを読み込む:

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に通信書き込み/読み取りを開始するスレッドは1つしかありません。私には、RS232を処理するスレッドのように、readUnitsData()が呼び出される前にリスナーが終了するのを常に待っています。私は大きなThread.sleep(15000)を追加したので、readUnitsData()の時間も増えました。私はそれらを使用する方法でrunnablesとリスナーを使用するかどうか、または何が問題になる可能性がありますか? – Jure

+0

さて、私はあなたのプログラム(https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)をデバッグしようとするよりも、他のアドバイスはしていません本当に何が起こるか見ることができます。 - 私が言ったように、あなたが提供したコードには問題はありませんが、マルチスレッドは難しいトピックであり、他のスレッドで実行するコードにはまだトラップが残っている可能性があります。それを取りなさい。この1つのスレッドのみを実行します。 (リモート)デバッグしたり、さらにログステートメントを追加することができます。何が起こるかを理解する。 –

答えて

1

@Markus Mitterauerが提案されていると離れて取ったように私がしましたコード。私はそれが間違っていたunitIDの1つに問題があることを発見しました。そのため、レジスタを読み込むときに値を取得せず、リスナーが正しくトリガされませんでした。

+0

あなたの質問に答えを*印してください。 –

関連する問題