有人能解释一下为什么这个程序执行后的输出会有这么大的不同吗?
首先,类:线程扩展java.lang.Thread
public class UsingThreadExtension extends Thread {
public UsingThreadExtension(String s) {
super(s);
}
@Override
public void run() {
for (int i=0; i<5; i++) {
System.out.println(i + " " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}Java.lang.Runnable的实现:
public class UsingRunnableImplementation implements Runnable {
@Override
public void run() {
for (int i=0; i<5; i++) {
System.out.println(i + " " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}和main类:
public class ThreadsExample {
public static void main(String[] args) {
UsingThreadExtension threadA = new UsingThreadExtension("Thread A");
UsingRunnableImplementation runnableImplementation = new UsingRunnableImplementation();
Thread threadB = new Thread(runnableImplementation, "Thread B");
//threadA.start();
threadB.start();
try {
//threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//threadA.run();
threadB.run();
System.out.println("Main thread says hello!");
}
}在此组合中,输出如下所示:
0 Thread B
1 Thread B
2 Thread B
3 Thread B
4 Thread B
Main thread says hello!在注释threadB部件和取消注释threadA之后,会出现如下内容:
0 Thread A
1 Thread A
2 Thread A
3 Thread A
4 Thread A
0 main
1 main
2 main
3 main
4 main
Main thread says hello!谁能告诉我,到底是什么原因造成了这样的差异?任何提示都很感谢。我猜,它与覆盖threadA中的java.lang.Thread.run()方法有关,但为什么threadB在第二种情况下不运行runnable?
发布于 2012-12-05 03:03:51
Second Case (**threadA.run()**):-
由于threadA是UsingThreadExtension类型的引用:-
UsingThreadExtension threadA = new UsingThreadExtension("Thread A");所以像这样调用threadA上的run方法:-
threadA.run();将仅在主线程中执行UsingThreadExtension的run方法。因此,线程的名称在第二个输出的0 main, 1 main, etc.中是main。
First Case (**threadB.run()**):-
因为threadB是一个Thread类型的引用,只指向Thread的一个实例。
Thread threadB = new Thread(runnableImplementation, "Thread B");因此,像这样调用它的run方法:
threadB.run();将仅在main线程中再次执行在Thread类中被覆盖的run()方法。但是因为Thread类的run()方法实际上不打印任何东西。因此,您没有获得threadB.run()的任何输出。
发布于 2012-12-05 02:56:34
发布于 2012-12-05 04:03:25
当您构造一个向其传递Runnable实例的Thread时,它将该实例存储在一个私有字段中。java.lang.Thread的默认run()方法本质上是
if(target != null) target.run();因此,假设在线程B中发生的情况是,您对线程执行start(),当它完成时,在内部执行target = null。然后,当您稍后调用线程的run()方法时,它不再具有对目标Runnable的引用,因此不会运行它。
如果反过来做,首先调用主线程上的run(),然后调用start(),您将看到两个大量的日志记录。
在extends Thread的情况下,run()方法被直接覆盖,因此绕过了这个null检查。
https://stackoverflow.com/questions/13709863
复制相似问题