2016-04-09 180 views
-2

我有2個嵌套while循環,如果我停止內部循環,外部停止檢查內部運行。我有方法來啓動和停止計時器,但如果我停止計時器,然後重新啓動它(設置布爾值爲true)計時器不會啓動。如果我在System.out.println(「test」)外部循環中執行一些操作,而內部暫停時,它可以正常工作。爲什麼while循環停止工作?

@Override 
protected synchronized Void call() throws Exception { 
    while(true){ 
     System.out.println(); 
     while(play){ 
      System.out.println(play); 
      secondCounter++; 
      seconds++; 
      if(seconds>59){ 
       secondCounter=0; 
       seconds=0; 
       minutes++; 
      } 
      if(minutes>59){ 
       minutes=0; 
       hours++; 
      } 
      System.out.println("Task sekunden: "+seconds); 
      setTime(); 
      Thread.sleep(1000); 
     } 
    } 
} 

下面是完整的類:

public class TimerTask extends Task<Void>{ 

private Label timer; 
private boolean play=false; 

private int secondCounter; 

private int seconds; 
private int minutes; 
private int hours; 

public TimerTask(Label timer){ 
    this.timer=timer; 
} 

@Override 
protected synchronized Void call() throws Exception { 
    while(true){ 
     while(play){ 
      System.out.println(play); 
      secondCounter++; 
      seconds++; 
      if(seconds>59){ 
       secondCounter=0; 
       seconds=0; 
       minutes++; 
      } 
      if(minutes>59){ 
       minutes=0; 
       hours++; 
      } 
      System.out.println("Task sekunden: "+seconds); 
      setTime(); 
      Thread.sleep(1000); 
     } 
    } 
} 

public int getMinutes(){ 
    int time; 
    time=minutes + (hours*60); 
    if(seconds>30){ 
     time++; 
    } 
    return time; 
} 

public void test(){ 
    String secondsTime; 
    String minutesTime; 
    String hoursTime; 

    if(seconds<10){ 
     secondsTime="0"+seconds; 
    }else{ 
     secondsTime=String.valueOf(seconds); 
    } 
    if(minutes<10){ 
     minutesTime="0"+minutes; 
    }else{ 
     minutesTime=String.valueOf(minutes); 
    } 
    if(hours<10){ 
     hoursTime="0"+hours; 
    }else{ 
     hoursTime=String.valueOf(hours); 
    } 

    System.out.println(hoursTime+":"+minutesTime+":"+secondsTime); 
} 

public void setTime(){ 
    String secondsTime; 
    String minutesTime; 
    String hoursTime; 

    if(seconds<10){ 
     secondsTime="0"+seconds; 
    }else{ 
     secondsTime=String.valueOf(seconds); 
    } 
    if(minutes<10){ 
     minutesTime="0"+minutes; 
    }else{ 
     minutesTime=String.valueOf(minutes); 
    } 
    if(hours<10){ 
     hoursTime="0"+hours; 
    }else{ 
     hoursTime=String.valueOf(hours); 
    } 
    Platform.runLater(() -> {timer.setText(hoursTime+":"+minutesTime+":"+secondsTime);}); 
} 

public void stop(){ 
    this.play=false; 
    System.out.println("Stop: "+play); 
} 

public void start(){ 
    this.play=true; 
    System.out.println("Start: "+play); 
} 

public void reset(){ 
    this.play=false; 
    secondCounter=0; 
    seconds=0; 
    minutes=0; 
    hours=0; 
    timer.setText("00:00:00"); 
    System.out.println("Reset: "+play); 
} 

}

+0

什麼是「遊戲」,你如何設置它? – user2004685

+0

你的問題很不清楚。顯示代碼,顯示您獲得的輸出和您期望的輸出。什麼是「玩」?它是如何定義的?當播放錯誤時,你是否真的想要一個繁忙的循環不斷地向輸出寫入新的行? –

+0

play是一個布爾值,我用一些公共setter和getter方法設置它 – Steinliiippp

回答

0

play被讀取並從多個線程修改,但不揮發。所以你不能保證它的可見性。一個線程可以將其設置爲true,另一個線程將其視爲永遠爲false。

其餘的代碼也不是線程安全的。所有的共享狀態都是在沒有任何同步的情況下訪問的。

所以你真的不能依賴任何代碼。

+0

我只是設置布爾值玩揮發性,它的作品...謝謝。我嘗試了與同步,但這讓整個圖形用戶界面。你能解釋我爲什麼嗎? – Steinliiippp

+0

本主題將解釋一本書。給你買一本「Java Concurrency in Practice」的副本,並閱讀它。如果你想認真對待Java中的多線程,這是必須閱讀的。 –