我有两个问题: 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);
}
}
}
答案 0 :(得分:5)
最重要的是,您需要更改
randomScore = (int) Math.random() * 1000;
到
randomScore = (int) (Math.random() * 1000);
^ ^
因为(int) Math.random()
总是等于0。
另一个需要注意的重要事项是主线程继续并打印randomScore
的值,而不等待另一个线程修改该值。尝试在Thread.sleep(100);
或start
之后添加student.join()
以等待学生帖子完成。
您还应该意识到Java内存模型允许线程缓存其变量值。可能是主线程缓存了它自己的值。
尝试使randomScore变得不稳定:
public static volatile int randomScore;
答案 1 :(得分:1)
student.join()
student.start()
run()
方法,那么它将更改randomScore
变量的值,但您应该像@aioobe建议的那样使这些更改可见。答案 2 :(得分:1)
它会更改值,但是在执行代码设置之前,您可以读取值。毕竟,它正在另一个线程中执行。
如果要保证在读取之前设置变量,可以使用CountdownLatch(在设置变量后创建1的锁存器和倒计时,在另一个线程中使用latch.await()
),或者或者使用Thread.join()
等待线程完成执行。
答案 3 :(得分:1)
代码中的真正问题是,在将数字乘以1000之前,将Math.random转换为int。
randomScore = (int) (Math.random()*1000);
当你的代码执行时会发生以下情况
您将随机分数设置为零(初始状态)
如果要更改随机分数
其余答案为您提供了代码不是线程安全的原因。
TL; DR:
在程序中调用run()方法
不会,因为随机评分算法中存在错误。实际上,每次执行run方法时,随机分数始终设置为0。
答案 4 :(得分:1)
是的,正在调用run
方法。但它可能太快了。您可以将thread
加入主thread
并等待一段时间。