Understanding the scope of this variables and the behavior of this thread (edited question)
The following thread is made to run unpredictably. Sometimes it may print ABC and others 123. I don't get why it's able to print ABC. Please explain its flow of execution.
public class ArrayDeclaration implements Runnable {
String [] s;
public ArrayDeclaration (String []s){
this.s=s;
}
public void run() {
synchronized (this){
try
{
wait(5000);
System.out.print(s[0]+s[1]+s[2]);
}
catch(InterruptedException ie){
}
}
}
}
/**
* @param args the command line arguments
*/class Test{
public static void main(String[]args)throws Exception {
String[] s = new String []{"1","2","3"};
ArrayDeclaration myRunnable = new ArrayDeclaration(s);
// TODO code application logic here
Thread t1 = new Thread(myRunnable);
t1.start();
t1.join(5000);
s[0]="A";
s[1]="B";
s[2]="C";
}
}
I don't get the scope of the String array. Why is it (sometimes) changed to ABC and p开发者_开发技巧rinted? Shouldn't the changes just affect its scope within main? Does this behavior has something to do with the String pool?
It's able to do that because of the timeout on the call to join combined with the wait of the same length in the ArrayDeclaration. So, you start the thread, which immediately does a wait(5000). You join for up to 5000 millis. The wait and the join both finish close enough to the same moment that one thread or the other might get the next time slice for execution depending on many external factors. In some cases, the main thread gets the first chance, so it sets the array members before the other thread prints them. In other cases, the printing thread gets the first chance.
If the join and wait were not the same length, it would be more predictable.
Both timers, wait
and join
have 5000 milliseconds as arguments, because computer clocks typically have a resolution of about 30ms, both timers run out at approximately the same time, making it impossible to predict what happens first, the code after the wait or the code after the join.
Changing the argument to join to 6000 milliseconds would make sure the thread can run its course and resulting in a successful join
and printing 123
always.
For one thing, you wait 5 secs in the thread, and you also join with a max wait time of 5 seconds.
Timing is difficult, the API does not guarantee exact timing. So I think that sometimes the join actually waits 4998 millis and the wait() is 5002 millis at which time the array is already changed. Not always of course, sometimes the other way around and then it prints 123. (Times mentioned are an example).
You can have a sequantial flow by using join() without a timeout.
The timeout on your join expires before the timeout on the wait. Even though they are both set to the same wait interval, whichever thread happens to run first and have its timeout expire will be fairly random. Thus resulting in the array contents being changed before the print occurs in random cases where the join expires first.
精彩评论