0

这是关于线程的代码.....我不知道这两个 new() 语句之间的区别。

  Runnable r=new Runnable() {
    public void run() {
    System.out.print("Cat");
    }
    };

    Thread t=new Thread(r) {
    public void run() {
    System.out.println("Dog");
    }
    };
    t.start();

输出是 Dog 但是为什么以及如何?

4

7 回答 7

3

因为你重写Thread#run()了,所以这个方法最终会在你启动线程的时候执行。默认Thread#run()委托给传入的Runnable. 经验法则:提供 aRunnable或 override Thread#run(),但不要两者都做!

于 2013-10-14T08:48:23.837 回答
1

在第一个“new”语句中,您创建了一个 Runnable 实例,您稍后将其传递到由第二个“new”语句创建的线程中。输出是 dog,就像在您创建线程的第二个“新”语句中一样,您还覆盖了 run() 方法,这必须优先于您传入的 Runnable 中 run() 的实现。这意味着您的从不使用打印 Cat 的 run() 的可运行实现,只有打印 Dog 的 run() 实现被线程调用。

于 2013-10-14T08:55:48.137 回答
1

在线程 t 中,您覆盖传递给它的 runnable 的 run 方法。我认为这就是为什么当您调用具有可运行的线程的开始并且不调用其运行方法时!

于 2013-10-14T08:48:21.610 回答
0

由于 Runnable 是一个接口,而 Thread 是一个类,因此 JVM 管理它们的方式存在一些差异。

- 如果你实现了 Runnable 接口,线程之间将共享一个唯一的对象。

- 扩展 Thread 类,每个线程都会创建一个对象。

在某些情况下,runnable 会比 Thread 消耗更少的内存。此外,我认为如果你扩展一个类,那是因为你想重写一些方法,所以从我的角度来看,如果你不会修改 Thread 类的任何方法或行为,你应该使用 Runnable..

希望能帮助到你。

于 2013-10-14T09:07:23.970 回答
0

例如,在创建 Thread 对象时,t您已经覆盖了run()方法。所以调用t.start()将执行覆盖的方法。所以输出是Dog而不是Cat

于 2013-10-14T08:51:40.190 回答
0

改成:

Runnable r=new Runnable() {
public void run() {
System.out.print("Cat");
}
};

Thread t=new Thread(r);
t.start();

这应该打印“猫”

于 2013-10-14T08:47:51.037 回答
0

将其更改为:

new Thread(new Runnable() {
    public void run() {
        System.out.print("Cat");
    }
}).start();

Runnable 接口提供了一种使用 Thread 类的替代方法,用于无法使您的类扩展 Thread 类的情况。这发生在我们的类,我们想在一个单独的线程上运行应该扩展一些其他类时。由于没有多重继承,我们的类不能同时扩展Thread类和另一个。在这种情况下,您的类必须实现 Runnable 接口。

于 2013-10-14T08:52:59.053 回答