2015-12-22 87 views
0

早上好,Java - while循環來檢查狀態並退出

我有一個使用while循環的問題。讓我解釋。我必須管理帶有紅外傳感器的燈。沒問題。 它以這種方式工作:如果發現移動,燈亮起,如果沒有移動被發現,超時將開始,並在此之後,光線下降,但如果在這個超時在一個新的移動注意到,超時必須停止,「重置」週期。

由於沒有「但」條件下,它會很容易有Tread.sleep來管理,但我想用一段時間週期沒有結果來完成它......

這是我有,每秒一次檢查一個無限循環,他傳感器狀態

while (true) { 
      try { 
       if (sensore.getStatoSensore() == 1) { //movement noticed 
        lampada.accendi(); //light on 

       } else if (sensore.getStatoSensore() == 0) { //no movement noticed 
        long start = System.currentTimeMillis(); 
        long end = start + (timeoutSpegnimento * 1000); //10 seconds before lights shut down 
        boolean movement = false; 
        while (System.currentTimeMillis() < end) { 
         logger.debug("Shutdown timer started"); 
         if (sensore.getStatoSensore() == 1) { 
          movement = true; 
          lampada.accendi(); //light up 
          logger.debug("Movement noticed - movement=" + movement); 

         } else { 
          movement = false; 
         } 

         Thread.sleep(500); 
        } 
        if (!movement) { 
         lampada.spegni(); //light off 
        } 

       } 
      } catch (Throwable e1) { 
       // TODO Auto-generated catch block 
       logger.error(e1); 
      } 
      try { 

       Thread.sleep(intervallo * 1000); //do the sensor check once a second 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       logger.error(e); 
      } 
     } 

,我發現了問題與超時環while (System.currentTimeMillis() < end) 在我的想法,它應該以這種方式工作: 如果(sensore.getStatoSensore() == 0)一段時間週期超時叫做。在此期間,如果沒有發現新動作,則movement爲假,因此調用lampada.spegni();。這部分運作良好。

但這如果條件

if (sensore.getStatoSensore() == 1) { 
           movement = true; 
           lampada.accendi(); //light up 
           logger.debug("Movement noticed - movement=" + movement); 

作品僅在第一次while循環中,不是也徹最初一段時間(true)循環被搞砸了,一句話,我不能得到正常的行爲了。我希望這更好的解釋什麼,我正在尋找

+1

作品「以一種奇怪的方式」..以什麼奇怪的方式?發生了什麼/出錯?你能指望什麼?你得到了什麼? – Stultuske

+0

我沒有在任何地方看到break語句。我猜猜,while(true)變成了一個無限循環嗎? – Stultuske

+0

while(true)循環必須是無限循環,它會連續檢查傳感器值。我的問題是在內部循環(System.currentTimeMillis() besmart

回答

1

當您在等待超時時發現移動時,您不會重置超時,就像您在說明中所述。

不要合併等待第一個移動,而燈仍然熄滅並等待超時過期。它們是完全不同的東西,即使您設法使其工作,也不應該嘗試將其放入一個循環中。

最好他們甚至應該在不同的,有名的方法。

我已經做了第一次刺激清理你的代碼,並且如果在燈亮時有移動,也重置超時。這應該對你有所幫助。

private boolean hasMovement() { 
    return sensore.getStatoSensore() == 1; 
} 

private static void waitSecond() { 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
    } 
} 

public void run() { 
    while (true) { 
     // Wait until movement noticed 
     while (!hasMovement()) { 
      waitSecond(); 
     } 
     // Movement noticed, turn light on 
     lampada.accendi(); 

     long lastMovementTime = System.currentTimeMillis(); 
     // Wait until 10 seconds from last movement 
     while (System.currentTimeMillis() < lastMovementTime + (timeoutSpegnimento * 1000)) { 
      if (hasMovement()) { 
       lastMovementTime = System.currentTimeMillis(); 
      } 
      waitSecond(); 
     } 

     // Turn light off 
     lampada.spegni(); 
    } 
+0

謝謝,這工作很好,並簡化了很多我的代碼,因爲現在我有一個真正的超時更新每個新的運動 – besmart

0

如果一個無限循環,是不是你的問題,只是使它沒有了Thread.sleep:

long lastMovement = 0L; 
while (true) { 
     try { 
      if (sensore.getStatoSensore() == 1) { //movement noticed 
       lampada.accendi(); //light on 
       lastMovement = System.currentTimeMillis(); 
      } else if (sensore.getStatoSensore() == 0) { //no movement noticed 
       long end = lastMovement + (timeoutSpegnimento * 1000); //10 seconds before lights shut down 
       if (end > System.currentTimeMillis() && lastMovement > 0) { 
        lampada.spegni(); //light off 
        lastMovement = 0L; 
       } 

      } 
     } catch (Throwable e1) { 
      // TODO Auto-generated catch block 
      logger.error(e1); 
     } 
     try { 

      Thread.sleep(intervallo * 1000); //do the sensor check once a second 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      logger.error(e); 
     } 
    } 
  • 運動?保存最後一次移動的時間戳
  • 不動?檢查當前時間戳>上次移動時間戳:如果爲true,則熄滅。
0

我認爲這是有用的添加方法,如「lampada.isOn()」,在任何時候,以標明燈(ON/OFF)的狀態。 就你而言,例如,當燈已經關閉時,沒有必要檢查超時。我認爲無限循環來自這個永久性檢查