Java线程实现的接口问题

如图,thread这个类实现了runnable这个接口,然后run方法里面执行的是外部传进来runnable接口实例的run方法。那么,在定义的时候实现runnable这个接口有什么用呢?不实现这个接口,run方法,不管是通过继承还是实现接口的方法来创建线程,似乎不受影响啊

img

img

该回答引用ChatGPT-3.5,仅为您提供参考,不保证完全正确
在 Java 中,线程可以通过两种方式来创建:

  1. 继承 Thread 类:你可以创建一个类,继承自 Thread 类,并覆盖 run() 方法来定义线程执行的任务。这种方式不需要实现 Runnable 接口,因为 Thread 类已经实现了 Runnable 接口,并将 run() 方法定义为接口的方法。这种方式是一种直接创建线程的方法。
class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的任务
    }
}
  1. 实现 Runnable 接口:你可以创建一个类,实现 Runnable 接口,并覆盖 run() 方法来定义线程执行的任务。然后,你可以将这个实现了 Runnable 接口的类实例化,并将其传递给 Thread 类的构造函数创建线程对象。这种方式是一种将任务与线程分离的方法,它可以更灵活地共享任务。
class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的任务
    }
}

// 创建线程并传递Runnable实例
Thread thread = new Thread(new MyRunnable());

关于你提到的情况,如果你直接在一个类中定义了 run() 方法,并且这个类没有显式实现 Runnable 接口,但仍然创建了线程并使用这个类的实例作为线程的执行体,这是因为 Thread 类本身已经实现了 Runnable 接口,并且它的 run() 方法就是在内部调用了传入的 Runnable 对象的 run() 方法。因此,不管是继承 Thread 还是实现 Runnable,最终线程都是通过 run() 方法来执行任务的。


实际上,推荐使用实现 Runnable 接口的方式来创建线程,因为它允许你更好地将任务和线程分离,从而提高了代码的灵活性。当你需要在多个线程之间共享同一个任务时,实现 Runnable 接口会更有优势。但是,如果你只是简单地创建一个线程来执行某个任务,继承 Thread 类也是可行的。


该回答引用NewBing,仅为您提供参考,不保证完全正确
你的问题是为什么Thread类要实现Runnable接口,而不是直接定义run方法。这里有几点需要说明:

  • Thread类实现Runnable接口是为了支持多态性,也就是说,一个Thread对象可以执行任何一个实现了Runnable接口的对象的run方法。这样可以让Thread类和具体的任务逻辑解耦,更加灵活和通用。
  • Thread类本身也重写了run方法,但是这个方法默认是空的,也就是什么都不做。如果你继承Thread类并重写run方法,那么你就覆盖了Thread类自己的run方法,相当于自定义了线程要执行的任务逻辑。
  • 如果你继承Thread类并且实现Runnable接口,那么你必须重写两个run方法,一个是Thread类的,一个是Runnable接口的。但是当你调用start方法时,只会执行Thread类的run方法,而不会执行Runnable接口的run方法。所以这种情况下,实现Runnable接口没有意义,除非你在Thread类的run方法中显式地调用Runnable接口的run方法。
  • 如果你不继承Thread类,而只是实现Runnable接口,那么你必须创建一个Thread对象,并把自己作为参数传给它,然后调用它的start方法。这样就会执行你实现的Runnable接口的run方法。这种方式更符合面向对象的设计原则,因为你只关注任务逻辑,而不关心线程管理。

总之,Thread类实现Runnable接口是为了支持多态性和灵活性,但是如果你继承Thread类并重写run方法,那么你就不需要再实现Runnable接口了。如果你只想实现任务逻辑,而不想继承Thread类,那么你就只需要实现Runnable接口,并把自己作为参数传给一个Thread对象即可。


源: 与必应的对话, 2023/9/7
(1) Java 多线程编程 | 菜鸟教程. https://www.runoob.com/java/java-multithreading.html.
(2) 史上最全面的40个Java多线程问题汇总与解析 - 知乎. https://zhuanlan.zhihu.com/p/102511862.
(3) java线程的两种方式Thread(类)、Runnable(接口)_程程呀的博客-CSDN博客. https://blog.csdn.net/qq_31755183/article/details/103709919.


该回答引用文心一言,仅为您提供参考,不保证完全正确
实现 Runnable 接口的主要目的是为了解决 Java 中单一继承的限制。在 Java 中,一个类只能继承一个类,但是可以实现多个接口。Runnable 接口允许我们定义一个类的行为,而不是继承一个类的结构。


让我们深入了解以下这个例子:

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Hello from MyRunnable!");
    }
}

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Hello from MyThread!");
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();  // 输出:Hello from MyRunnable!

        MyThread myThread = new MyThread();
        thread = new Thread(myThread);
        thread.start();  // 输出:Hello from MyThread!
    }
}

在上述代码中,MyRunnable 类实现了 Runnable 接口,并重写了 run 方法。MyThread 类继承了 Thread 类,并重写了 run 方法。在 Main 类中,我们创建了 MyRunnableMyThread 的实例,并将它们作为线程的参数传递给 Thread 类的构造函数。然后,我们调用 start 方法来启动线程。


现在,如果你尝试将 MyThread 类改为不实现 Runnable 接口,而是直接继承自 Thread 类,那么你将无法将该类的实例作为参数传递给 Thread 类的构造函数。这就是为什么我们需要实现 Runnable 接口的原因。它允许我们定义一个类,该类可以作为线程的参数,并且可以执行我们希望线程执行的任务。


该回答引用讯飞星火,仅为您提供参考,不保证完全正确
在Java中,实现Runnable接口的主要目的是为了让一个类能够被多线程执行。具体来说,有以下几个原因:

  1. 允许将实现了Runnable接口的类的实例作为参数传递给Thread类的构造函数,从而创建一个新的线程并启动它。这样可以让不同的线程执行不同的任务,提高程序的并发性能。

  2. 当一个类实现了Runnable接口时,它可以将自己的实例传递给其他线程,从而实现线程间的通信和协作。例如,一个线程可以负责生成数据,另一个线程可以负责处理这些数据。

  3. 实现Runnable接口是Java多线程编程的基本要求。如果不实现这个接口,那么创建线程的方式将受到限制,只能通过继承Thread类或使用Executor框架来实现。

总之,实现Runnable接口是为了方便地创建和管理线程,提高程序的并发性能和可扩展性。

run方法相当于子线程的主方法,你要是光开新线程但是没有操作那也没意义吧

【以下回答由 GPT 生成】

问题解答:

当定义线程时实现Runnable接口,有以下几个作用:

  1. 分离任务:通过实现Runnable接口,可以将任务的定义与线程的定义分离开来。这样,线程可以专注于线程的生命周期和控制,而任务可以在不同的线程中共享和复用。
  2. 避免单继承限制:在Java中,一个类只能继承自一个父类。如果线程类直接继承Thread类,那么它失去了继承其他类的能力。而实现Runnable接口,则可以同时继承其他类。
  3. 线程池复用:通过实现Runnable接口,可以方便地将线程提交给线程池进行管理和复用。
  4. 接口的多重实现:Java中,一个类可以实现多个接口,这给代码的设计带来了更大的灵活性。通过实现Runnable接口,线程类可以同时实现其他接口,达到更好的代码组织结构。

相比于继承的方式,选择实现Runnable接口来创建线程的好处有:

  1. 避免单继承限制:通过继承Thread类创建线程,会导致这个类失去继承其他类的能力。
  2. 代码复用性:通过实现Runnable接口,可以将任务与线程分离,从而可以在不同的线程中共享和复用相同的任务。

Runnable接口和继承的方式在创建线程时的区别如下:

  1. 继承Thread类创建线程:这种方式需要直接继承Thread类,并重写Thread类中的run方法来定义线程的具体逻辑。创建的线程对象既是线程本身,也是任务本身。这种方式简单直接,但受到了单继承限制。 java public class MyThread extends Thread { @Override public void run() { // 线程的具体逻辑 } }

  2. 实现Runnable接口创建线程:这种方式创建线程的类需要实现Runnable接口,并重写run方法来定义线程的具体逻辑。任务的实例通过构造函数传递给线程对象。这种方式避免了单继承限制,同时也将任务与线程进行了分离。 java public class MyRunnable implements Runnable { @Override public void run() { // 线程的具体逻辑 } }

run方法中执行外部传入的Runnable接口实例的run方法的意义是,将线程的执行逻辑与具体任务的逻辑分离开来。通过将任务封装在Runnable接口的实例中,并将该实例传递给线程对象,在线程执行时调用Runnable接口实例的run方法,实现了任务与线程的解耦。这样,可以方便地替换任务或在不同的线程中复用相同的任务。

不实现Runnable接口,直接重写Thread类的run方法会导致以下影响:

  1. 失去了任务的封装:任务的逻辑没有被封装在独立的Runnable接口实例中,而是直接写在了Thread的子类中。
  2. 任务与线程耦合:任务的逻辑与线程的逻辑紧密耦合在一起,不容易进行任务的替换或在多个线程间复用任务。

综上所述,实现Runnable接口是一种更好的创建线程的方式,它能够更好地分离任务和线程,并提供了更大的灵活性和代码组织结构。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^