Reputation: 9
I have some questions about final. The code is as follows
public class Demo {
private static Thread thread;
public static void main(String[] args) {
for (int i = 0; i < 4; i++) {
fun("url-" + i);
}
}
public static void fun(final String url) {
if (thread == null) {
thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(url);
}
});
}
thread.run();
}
}
output:
url-0
url-0
url-0
url-0
why? I think it looks something like this
url-1
url-1
url-3
url-4
Upvotes: 0
Views: 60
Reputation: 140
You are not getting the expected output because you are instantiating the Thread
only once with the first argument 'url-0'. Then, each time you call the method fun
, you are just calling the method run on the only one created thread thread.run() with the argument 'url-0'
Upvotes: 0
Reputation: 140427
That keyword final on the parameter has nothing to do with what you observe.
What really happens here: you create one thread object, that is an instance of an anonymous inner subclass of Thread. And that instance gets url-0 as parameter. Then, afterwards, you call the run()
method of that one Thread object 4 times. Thus the same object prints the same string 4 times.
To be more precise:
fun()
, the static thread
field is nullAnd as outlined in the comments: just calling run()
on a thread object doesn't cause a real OS thread to do work in parallel. You have to call start()
instead. But of course, it absolutely makes no sense to call start()
repeatedly for the same thread.
So, in order for your code to do more of what you expect, try this:
public class Demo {
public static void main(String[] args) {
for (int i = 0; i < 4; i++) {
fun("url-" + i);
}
}
public static void fun(String url) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(url);
}
});
thread.start();
}
}
Upvotes: 1
Reputation: 45309
You are defining your Thread
object once. It's this only instance that's being used with each subsequent invocations of your fun
method. This has nothing to do with the fact that url
is final
If you change your method implementation to something like this (making thread
a local-scoped variable), you'll see that you get the expected output:
public static void fun(String url) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(url);
}
});
thread.run();
}
In other words, when you create your Thread
object, it remembers the value of url
that was passed to it. And because you are NOT creating other Thread
objects when the url
parameter takes a different value, you can only see the value of url
that was passed when the object was created, which explains why you see url-0
every time.
Upvotes: 1