2011-02-13 350 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并等待一段时间。

相关问题