2016-06-13 6 views
1

Мне нужно сделать DieTester для школы. Один, который катит кости 100 раз, а затем помещает результат в таблицу и другую таблицу. Проблема в том, что моя тема не будет спать со временем, установленным слайдером. Вот мой DieTester:Sleep a Thread in a loop

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(), он правильно установит время, но Thread не спит или что-то в этом роде.

+0

В соответствии с кодом, * Thread.sleep (GetTime()); in for loop * наверняка сделает сон для текущего потока для getTime() миллисекунд, этот вызов будет гарантировать, что сон будет по крайней мере в указанное время, но вы не можете быть уверены, что поток начнет работать точно после данного время. Вы можете гарантировать, что поток будет спать в течение того времени, которое передается в методе sleep(), если нет прерванного исключения, иначе поток получит InterruptedException, которое вы можете проверить. – pbajpai21

+0

_ «Нить не будет спать со временем, установленным слайдером» _ - Сон слишком много или слишком мало? Сколько фактического времени сна отличается от запрошенного времени? Без жестких цифр очень сложно угадать, что происходит. –

+0

Нить не спит вообще, кажется, так что ваш вопрос, он слишком спит. – Faalhaaz

ответ

0

Ok ребята, так что я понял это, это то, что я сделал

@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 

Темы доступа к ней одновременно (один читает, один пишет), но он не имеет надлежащей синхронизации, так пишет один поток не гарантируется видимый другой нитью.

Кроме того, l инициализируется равным 0, а коэффициенты - это порожденная нить, протекающая через 100 циклов, не спящих прежде, чем произойдет первое событие изменения свойства.

+0

Так что же я делаю? – Faalhaaz

+0

Ну, используйте правильную синхронизацию (сделать l volatile будет достаточно, учитывая ваш текущий код). Для состояния гонки я не знаю, это зависит от того, чего вы хотите достичь. Может быть, вы хотите начать с большего значения по умолчанию или только начать поток, как только значение, отличное от 0, известно для l? – bowmore