为什么run方法没有被调用?

3

我有两个问题: 1. 为什么当我运行程序时run()方法没有被调用? 2. 如果run()方法被调用,它会改变randomScore的值吗?

    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个回答

5

最重要的是,您需要进行更改。

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

为了

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

(int) Math.random()总是等于0。


另一个需要注意的重要事项是,主线程会继续执行并打印出randomScore的值,而不会等待其他线程修改该值。请在start后添加Thread.sleep(100);,或者使用student.join()等待学生线程完成。


您还应该知道Java内存模型允许线程缓存变量的值。可能是主线程缓存了自己的值。

尝试将randomScore设置为volatile:

public static volatile int randomScore;

我只是再增加一个问题。你可以帮我吗? - John

1
你代码中的真正问题是在将 Math.random 强制转换为 int 之前,你将其乘以 1000。
  randomScore = (int) (Math.random()*1000);

当您的代码执行时,会发生以下情况:

  1. 您将随机分数设置为零(初始状态)

  2. 当您想要更改随机分数时

    1. Math.random创建一个双精度值,该值大于或等于0且小于1
    2. 您将双精度值转换为int,其始终为0
    3. 您将0乘以1000,得到随机分数为0。

其余的答案告诉您为什么您的代码不是线程安全的。

简而言之:

  1. 在您的程序中调用run()方法

  2. 不会,因为随机评分算法存在错误。实际上,在每次执行run方法时,随机分数总是设置为0。


1
  1. 你的run方法被调用了,但是你没有等待它完成。在student.start()之后添加student.join()
  2. 如果调用run()方法,它将改变randomScore变量的值,但你应该像@aioobe建议的那样使这些更改可见。

1

它会改变值,但是你读取值的操作可能在代码执行设置之前发生。毕竟它是在另一个线程中执行的。

如果你想保证变量在读取之前被设置,你可以使用CountdownLatch(创建一个计数器为1的latch,在设置变量后倒数,在另一个线程中使用latch.await()),或者使用Thread.join()等待线程执行完毕。


1

是的,run方法正在被调用。但可能太快了。您可以将 thread 与主 thread 进行连接并等待一段时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接