我有一些关于期末考试的问题。代码如下
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发布于 2019-05-10 18:50:33
参数上的关键字final与您观察到的内容无关。
这里实际发生了什么:您创建了一个Thread线程对象,它是的匿名内部Thread子类的一个实例。该实例将url-0作为参数。然后,调用该Thread对象的run()方法4次。因此,相同的对象打印相同的字符串4次。
更准确地说:
fun()时,static Thread域为空,因此创建了一个新实例,并将传入的字符串复制到该( thread的子类)对象的上下文中。该字符串是“url-0”,然后对该对象调用正如评论中所概述的:仅仅在线程对象上调用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();
}
}发布于 2019-05-10 18:51:56
您只需定义一次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的值。而且,因为当url参数采用不同的值时,您不是在创建其他Thread对象,所以您只能看到创建对象时传递的url的值,这就解释了为什么每次都会看到url-0。
发布于 2019-05-10 19:00:33
您无法获得预期的输出,因为您使用第一个参数‘-0’实例化了url once。然后,每次调用方法fun时,都只是使用参数'url-0‘调用在唯一创建的线程thread.run()上运行的方法。
https://stackoverflow.com/questions/56075980
复制相似问题