2016-06-13 20 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

玉傢伙,所以我想通了,這是我做的

@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

那麼,使用適當的同步(使您的當前代碼使揮發性就足夠了)。 對於競爭條件,我不知道,這取決於你想達到什麼。也許你想從一個更大的默認值開始,或者只有在非0值爲l的情況下才啓動線程? – bowmore