首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 6线程-- "implements“和"extends”的不同行为

Java 6线程-- "implements“和"extends”的不同行为
EN

Stack Overflow用户
提问于 2012-12-05 02:51:13
回答 3查看 1.4K关注 0票数 2

有人能解释一下为什么这个程序执行后的输出会有这么大的不同吗?

首先,类:线程扩展java.lang.Thread

代码语言:javascript
复制
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的实现:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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!");
    }
}

在此组合中,输出如下所示:

代码语言:javascript
复制
0 Thread B

1 Thread B

2 Thread B

3 Thread B

4 Thread B

Main thread says hello!

在注释threadB部件和取消注释threadA之后,会出现如下内容:

代码语言:javascript
复制
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?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-05 03:03:51

Second Case (**threadA.run()**):-

由于threadAUsingThreadExtension类型的引用:-

代码语言:javascript
复制
UsingThreadExtension threadA = new UsingThreadExtension("Thread A");

所以像这样调用threadA上的run方法:-

代码语言:javascript
复制
threadA.run();

将仅在主线程中执行UsingThreadExtension的run方法。因此,线程的名称在第二个输出的0 main, 1 main, etc.中是main。

First Case (**threadB.run()**):-

因为threadB是一个Thread类型的引用,只指向Thread的一个实例。

代码语言:javascript
复制
Thread threadB = new Thread(runnableImplementation, "Thread B");

因此,像这样调用它的run方法:

代码语言:javascript
复制
threadB.run();

将仅在main线程中再次执行在Thread类中被覆盖的run()方法。但是因为Thread类的run()方法实际上不打印任何东西。因此,您没有获得threadB.run()的任何输出。

票数 4
EN

Stack Overflow用户

发布于 2012-12-05 02:56:34

票数 3
EN

Stack Overflow用户

发布于 2012-12-05 04:03:25

当您构造一个向其传递Runnable实例的Thread时,它将该实例存储在一个私有字段中。java.lang.Thread的默认run()方法本质上是

代码语言:javascript
复制
if(target != null) target.run();

因此,假设在线程B中发生的情况是,您对线程执行start(),当它完成时,在内部执行target = null。然后,当您稍后调用线程的run()方法时,它不再具有对目标Runnable的引用,因此不会运行它。

如果反过来做,首先调用主线程上的run(),然后调用start(),您将看到两个大量的日志记录。

extends Thread的情况下,run()方法被直接覆盖,因此绕过了这个null检查。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13709863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档