I have 2 qu开发者_运维知识库estions: 1. why run() is not called when I run the program 2. if run() is called, will it change the value of 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);
}
}
}
Most importantly, you need to change
randomScore = (int) Math.random() * 1000;
to
randomScore = (int) (Math.random() * 1000);
^ ^
since (int) Math.random()
always will equal 0.
Another important thing to notice is that main thread continues and prints the value of randomScore
without waiting for the other thread to modify the value. Try adding a Thread.sleep(100);
after the start
, or student.join()
to wait for the student thread to finish.
You should also be aware of the fact that the Java memory model allows for threads to cache their values for variables. It may be that the main thread has cached it's own value.
Try making the randomScore volatile:
public static volatile int randomScore;
- Your run method is called but you're not waiting for it to complete. Add
student.join()
after thestudent.start()
- If the
run()
method is called then it will change value of therandomScore
variable but you should do like @aioobe suggests to make these changes visible.
It will change the value, but your reading of the value may happen before the code has executed to set it. It is executing in another thread, after all.
If you want to guarantee the variable being set before reading, you could use a CountdownLatch (create a latch of 1 and countdown after setting the variable, in the other thread use latch.await()
), or alternatively use Thread.join()
to wait for the thread to finish execution.
Yeah, the run
method is being called. But it may be too quick. You can either join the thread
with main thread
and wait for a while.
The real problem in your code is that you cast Math.random as int before you multiply it by 1000.
randomScore = (int) (Math.random()*1000);
While your code executes the following happens
You set random score to zero (inital state)
When you want to change the random score
- Math.random creates a double value that is equal to or greater than 0 and less than 1
- You cast the double to an int which is always 0
- You multiply 0 by 1000 that gives you a random score of 0.
The rest of the answers gives you reasons why your code is not thread safe.
TL;DR:
The run() method is called in your program
No, it will not as there's a bug in the random scoring algorithm. Actually, random score is always set to 0 on every execution of the run method.
精彩评论