我对决赛有一些疑问。代码如下
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();
}
}
输出:
url-0
url-0
url-0
url-0
为什么?我认为看起来像这样
url-1
url-1
url-3
url-4
答案 0 :(得分:1)
该参数上的关键字 final 与您观察到的无关。
这实际上发生了什么:您创建一个一个线程对象,该对象是Thread的匿名内部 sub 类的实例。该实例将url-0作为参数。然后,此后,您将调用该线程对象的run()
方法4次。因此,同一对象将打印相同的字符串4次。
更准确地说:
fun()
时,静态thread
字段为空并且如注释中所概述:仅在线程对象上调用run()
不会导致真正的OS线程并行工作。您必须改为致电start()
。但是,当然,对于同一线程,重复调用start()
绝对没有意义。
因此,为了使您的代码做更多的预期工作,请尝试以下操作:
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();
}
}
答案 1 :(得分:1)
您一次定义了Thread
对象。每次fun
方法的后续调用都使用该实例。 这与url
是final
如果将方法实现更改为类似的内容(使thread
为局部作用域变量),则会看到预期的输出:
public static void fun(String url) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(url);
}
});
thread.run();
}
换句话说,当您创建Thread
对象时,它会记住传递给它的url
的值。而且,由于Thread
参数取不同值时没有创建其他url
对象,因此只能看到创建对象时传递的url
的值,这说明了原因您每次都会看到url-0
。
答案 2 :(得分:0)
您没有获得预期的输出,因为您仅使用第一个参数'url-0'实例化了Thread
仅一次。然后,每次调用方法fun
时,您只是在唯一一个创建的线程thread.run()上使用参数'url-0'调用该方法