2011-02-13 123 views
3

我有2個問題: 1.爲什麼運行程序時不會調用run() 2.如果調用run(),它是否會更改randomScore的值?爲什麼run方法不被調用?

import java.*; 


public class StudentThread extends Thread { 
    int ID; 
    public static volatile int randomScore; //will it change the value of randomScore defined here? 
     StudentThread(int i) { 
      ID = i; 
     } 

     public void run() { 
      randomScore = (int)(Math.random()*1000); 
     } 

public static void main(String args[]) throws Exception { 
    for (int i = 1;i< 10 ;i++) 
    { 
      StudentThread student = new StudentThread(5); 
      student.start(); 
      System.out.println(randomScore); 
    }    
} 
} 

回答

5

最重要的是,你需要改變

randomScore = (int) Math.random() * 1000; 

randomScore = (int) (Math.random() * 1000); 
        ^    ^

因爲(int) Math.random()始終將等於0


注意到另一個重要的事情是,主要線程繼續並打印randomScore的值,而不等待另一個線程修改該值。嘗試在startstudent.join()之後添加Thread.sleep(100);以等待學生線程完成。


您還應該意識到Java內存模型允許線程緩存變量值的事實。這可能是主線程緩存了它自己的值。

嘗試使randomScore揮發性:

public static volatile int randomScore; 
+0

abt問題1如何? – John

+0

已更新的答案。 – aioobe

+0

我只是再添加1個問題。你可以幫我嗎? – John

1
  1. 你的run方法被調用,但你不等待它完成。在student.start()
  2. 如果run()方法被調用,然後它會改變randomScore變量的值,但你應該做的像@aioobe建議進行這些更改後可見添加student.join()
1

它會改變的價值,但在此之前的代碼執行來設置它的價值的讀數可能發生。畢竟,它正在另一個線程中執行。

如果你想保證變量讀取之前被設置,你可以使用一個CountdownLatch(創造的1和倒計時閂鎖設置變量後,在其他線程使用latch.await()),或者使用Thread.join()等待線程完成執行。

1

在你的代碼真正的問題是,你投的Math.random爲INT您通過1000

randomScore = (int) (Math.random()*1000); 

乘前當你的代碼執行發生以下情況

  1. 您可以設置隨機得分爲零(初始狀態)

  2. 當你想改變隨機分數

    1. 數學。隨機產生的double值等於或大於0且小於1
    2. 你投雙爲int這始終是0
    3. 您0乘以1000,讓您的0
    4. 隨機分

其餘答案給出了爲什麼你的代碼不是線程安全的原因。

TL; DR:

  1. 的run()方法被調用程序中的

  2. 沒有,也不會因爲有一個在隨機評分算法的錯誤。實際上,每次執行run方法時,隨機得分總是設置爲0。

+0

非常感謝! – John

1

是的,run方法正在被調用。但它可能太快。您可以加入thread與主thread並等待一段時間。

相關問題