关于实现Runnable的问题

时间:2012-03-07 16:19:23

标签: java multithreading

  

可能重复:
  Java: “implements Runnable” vs. “extends Thread”

我有两个关于多线程编程的问题。我在网上看了几个答案,但我仍然找不到令人满意的答案。

  1. 实现Runnable比扩展线程类更受欢迎。为什么呢?

  2. 我们如何能够完全覆盖run()方法?

  3. 根据Herbert Schildt撰写的“The Complete Reference to Java”,如果我们没有覆盖除run()之外的Thread类的任何方法,那么我们最好实现Runnable。

    我的第二个问题可能听起来有些愚蠢,但我似乎错过了一些东西,而且我不确定整个问题是如何运作的。

4 个答案:

答案 0 :(得分:5)

  

1:实现Runnable比扩展线程类更受欢迎。为什么呢?

因为它允许你的类扩展另一个类,如果它想要而不是被迫扩展Thread

  

2:我们如何能够完全摆脱run()方法?

您当然可以覆盖其他方法,但Thread对象将在线程启动时调用run()方法。这就是它的工作原理。默认的Thread.run()方法是:

public void run() {
    if (target != null) {
        target.run();
    }
}

如果您使用Thread调用Runnable构造函数,则target设置为Thread。如果你改为扩展@Overriderun() Thread方法,那么这就是在线程对象启动时将被调用的方法。

这就是run()类的工作原理。

  

2:我们如何能够完全摆脱run()方法?

您可能在这里遇到了错误,而是询问为什么我们只需要在Runnable()实施 run()方法。

  • Runnable是一个具有必须实施的final方法的界面。
  • Thread是您扩展的具体类。除非类为final或方法为implement,否则您可以覆盖具体类中的任何方法。

确保使用正确的Java术语,不要混淆override和{{1}}。

答案 1 :(得分:0)

在你深入研究之前有三个基本原则。

  • 一个班级只能extend一个班级。
  • 一个类可以implement任意数量的接口。
  • 接口可以extend任意数量的接口。

此外,abstract类是一个类。所以它的行为就像一个类,你不能implement它。你只有extend

答案 2 :(得分:0)

如果扩展Thread,可能会出现许多陷阱,而实现Runnable则无法实现。

public static String getName() {
    return "My Test Application";
}

public static void stop() {
    System.out.println("Shutting down");
}

public static void main(String... args) {
    new Thread() {
        @Override
        public void run() {
            System.out.println(getName());
            stop();
        }
    }.run();
    System.out.println("Bye now.");
}

打印

Thread-0
Bye now.

查看您可以发现的错误数量。

答案 3 :(得分:0)

不必要的继承通常是一个坏主意。你可能经常听到“喜欢构图而不是继承”。我相信谷歌可以为你提供足够的链接。一般问题是继承在类之间带来了紧密的,不必要的耦合。

GUI组件也是如此,顺便说一句。