2016-06-13 8 views
1

私は学校のためにDieTesterを作る必要があります。ダイスを100回転がし、テーブルチャートと別のテーブルに出力します。 問題は、スレッドがSliderによって設定された時間にスリープ状態にならないことです。 ここに私のDieTester:ループでスレッドスリープ

ここ
package sample.Controllers; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.RunnableFuture; 

public class DieTester implements Runnable{ 
private Thread t; 
private String Threadname; 
List<Integer> List = new ArrayList(); 
Random rand = new Random(); 

long l; 

public DieTester(String name){ 
    Threadname = name; 
} 

public void run() { 

    for (int n = 0; n < 100; n++) { 
     try { 
      Thread.sleep(getTime()); 
      List.add(rand.nextInt(6) + 1); 
      System.out.println(List.get(n)); 

     } catch (InterruptedException e) { 
      System.out.println("Error"); 
     } 
    } 
} 

public void start(){ 
    if (t == null) 
    { 
     t = new Thread (this, Threadname); 
     t.start(); 

    } 
} 

public void setTime(double SliderTime){ 
    l = (long) SliderTime; 
} 

public long getTime(){ 
    return l; 
} 
} 

コントローラ:

package sample.Controllers; 
import javafx.event.Event; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.scene.control.Slider; 


public class Controller { 

DieTester dice = new DieTester("Time"); 

double time=0; 
EventHandler e = new EventHandler() { 
    @Override 
    public void handle(Event event) { 
     time = TimeSlider.getValue(); 
    } 
}; 


@FXML 
Slider TimeSlider = new Slider(50, 2000, 50); 




@FXML 
public void HandlePauseResumeAction(){ 
} 

@FXML 
public void HandleStartAction(){ 
    DieTester die = new DieTester("Start"); 
    die.start(); 

} 

@FXML 
public void HandleSlider(){ 

    TimeSlider.valueProperty().addListener((observable, oldValue, newValue) -> { 
     time = TimeSlider.getValue() * 20; 
     //System.out.println(time); 

     dice.setTime(time); 

    }); 

    System.out.println(dice.getTime()); 



} 



} 

スライダと、すべてが適切に設定されています。そして私がgetTime()を呼び出すと、時間が適切に出ますが、スレッドはスリープ状態ではありません。

+0

をやったことで、*のThread.sleep(getTime()); forループではgetTime()ミリ秒の現在のスレッドで確実にスリープしますが、この呼び出しではスリープ時間は少なくとも一定時間は確保されますが、指定された時間後にスレッドが正確に実行されることは保証されません時間。 sleep()メソッドで渡された時間の間、スレッドがスリープ状態になることを保証することができます。そうでない場合、スレッドはInterruptedExceptionを取得して検証できます。 – pbajpai21

+0

_ "スライダーで設定された時間にスレッドが眠れない" _ - それはあまりにも少なすぎるか眠っていませんか?実際のスリープ時間は要求された時間とどのくらい異なりますか?ハードな数字がなければ、何が起こっているのかを推測することは非常に難しいです。 –

+0

スレッドはまったく眠っていないので、あなたの質問は、それはあまりにも眠りません。 – Faalhaaz

答えて

0

[OK]をみんながそう、私はそれを考え出した、これは私は、コードを1として

@FXML 
public void HandleStartAction(){ 
    start(); 
} 

public void run(){ 
    for(int n = 0; n < 100; n++){ 
     try { 
      if(!suspend){ 
       Thread.sleep((long)TimeSlider.getValue() * 20); 
       List.add(rand.nextInt(6) + 1); 
       System.out.println(List.get(n)); 
      }else{ 

      } 

     } catch (InterruptedException e) { 
      System.out.println("Error"); 
     } 
    } 
} 

public void start(){ 
    if (t == null) 
    { 
     t = new Thread (this, "Start"); 
     t.start(); 

    } 
} 
1

これは変更可能な共有変数です:

long l 

のスレッドが同時にそれにアクセスし、(1は1の書き込み、読み込み)、まだそれが適切な同期を持っていない、そうであることが保証されていない1つのスレッドの書き込み他のスレッドに見える。

これに加えて、lは0に初期化され、生成されたスレッドは、最初のプロパティ変更イベントが発生する前に、実際にスリープすることなく100回のループで競い合っています。

+0

どうしたの? – Faalhaaz

+0

さて、適切な同期を使用してください(l volatileはあなたの現在のコードで十分です)。 競争状態については、私はあなたが達成したいものに依存しているかどうかは分かりません。おそらく、より大きなデフォルト値から始めたいのであれば、あるいは0以外の値がlについて分かったら、スレッドを開始するだけかもしれません。 – bowmore