this question is probably pretty easy to answer but I just don't get it. I reduced my problem until this little piece of code was left in order to find the "origin" of this problem: I'm trying to fill an ArrayList of Threads with a loop.
public static int u=0;
public void test(){
while (u <10) {
synchronized(threadList){
threadList.add(u, new Thread(){
@Override public void run(){
System.out.println("Thread at Index: " + u);
}
});
}
u++;
}
threadList.get(2).start();
}
With the last line I wanted to test the loop above by starting the thread at Index '2'. I'm expecting the console to show "Thread at Index: 2" but instead this is shown: "Thread at Index: 10" No matter which integer I write in the ".get(int)"-method, I receive the index '10'.
Why is that? And how to fix this?
The creation of the threads seems to work...so is the integer 'u' the problem?
I appreciate any kind of help! Thanks in advance!
When you reference u
in your run
method
@Override public void run(){
System.out.println("Thread at Index: " + u);
}
The current value of u
is retrieved. At the end of your loop and when the thread runs, that value is 10
.
Try the following
public static int u = 0;
public void test(){
while (u <10) {
synchronized(threadList){
threadList.add(u, new Thread(){
int i = u;
@Override public void run(){
System.out.println("Thread at Index: " + i);
}
});
}
u++;
}
threadList.get(2).start();
}
In your anonymous Thread
class, you're setting an instance field i
to the value u
has when the constructor is called and printing that value when the run()
is executed.
You reference u
in a context that hasn't been executed yet, a thread. When the run()
method eventually gets called, the program will evaluate the variable u
, but at that point in the execution of the program, its value will be 10. If, instead, you do the above, the variable i
will hold the value at that exact moment. This is because when new Thread
gets started and executed, field initialization occurs and u
is evaluated right away.
while (u <10) {
synchronized(threadList){
final int u_final = u;
threadList.add(u, new Thread(){
@Override public void run(){
System.out.println("Thread at Index: " + u_final );
}
});
}
u++;
}
with a final
variable, it is clear what its value will be, since it'll never change.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With