Java 这两种启动线程的方法有什么区别?

Java 这两种启动线程的方法有什么区别?,java,concurrency,multithreading,Java,Concurrency,Multithreading,如果我有一个实现Runnable接口的类,那么main方法中这些语句之间的区别是什么 MyThread t1 = new MyThread(); t1.start(); 及 第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个新线程来运行Runnable的run()方法。第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个运行run()的新线程方法。在第二个方法中,您创建了一个不包含在变量中的新线程,并启动这个新线程。t2保持不变 在第一个中,您创建t1

如果我有一个实现Runnable接口的类,那么main方法中这些语句之间的区别是什么

MyThread t1 = new MyThread();
t1.start();


第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个新线程来运行Runnable的run()方法。

第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个运行run()的新线程方法。在第二个方法中,您创建了一个不包含在变量中的新线程,并启动这个新线程。t2保持不变

在第一个中,您创建t1并开始


我认为,第二个线程是没有意义的,在第二个线程中,您创建了一个新的线程,而这个线程不包含在变量中,然后启动这个新线程。t2保持不变

在第一个中,您创建t1并开始


我认为,第二个是没有意义的

每当您的类必须扩展另一个类时,请使用Runnable


并且Runnable接口只包括run方法not start。

当您的类必须扩展另一个类时,请使用Runnable


而Runnable接口只包括run方法not start。

既然您使用了
t1.start()
,我假设MyThread扩展了线程。在这种情况下,第一个是正确的


第二个线程创建一个新线程,然后在另一个线程中启动任务。一个线程被浪费了。

既然您使用了
t1.start()
,我假设MyThread扩展了线程。在这种情况下,第一个是正确的


第二个线程创建一个新线程,然后在另一个线程中启动任务。一个线程被浪费了。

要在Java中实现一个线程,基本上有两种选择。第一:扩展类线程并实现run方法。你的例子似乎就是这样。在这种情况下,应该调用Thread.class的start()方法。这是您提供的两种变体之一

第二个变量是实现Runnable接口。在这种情况下,您还实现了run方法,但是您的类没有开始,因此您创建了一个新的Thread类,并将Runnable作为参数(正如您在第二个示例中所做的那样)。但如果你已经扩展了线程,那就没有意义了


我个人更喜欢实现Runnable,因为我不改变线程的行为(这将扩展它),而只使用线程功能。

要在Java中实现线程,基本上有两种选择。第一:扩展类线程并实现run方法。你的例子似乎就是这样。在这种情况下,应该调用Thread.class的start()方法。这是您提供的两种变体之一

第二个变量是实现Runnable接口。在这种情况下,您还实现了run方法,但是您的类没有开始,因此您创建了一个新的Thread类,并将Runnable作为参数(正如您在第二个示例中所做的那样)。但如果你已经扩展了线程,那就没有意义了


我个人更喜欢实现Runnable,因为我不改变线程的行为(这将扩展它),而只使用线程功能。

假设
MyThread
只实现
Runnable
接口,第二个代码段就是正确的使用模式
Thread.start()
链接到一个本机方法,该方法将启动一个新线程。然后,它将调用自己的
run()
,这将对其实例
Runnable
变量调用
run()
。在您的第二个代码片段中,这将是
MyThread
的一个实例,您的
Runnable

根据您提供的信息,第一个代码段将不会编译,除非:

  • 您已经自己实现了
    start
    方法。如果是这种情况,代码将不会启动新线程,并且只按照
    MyThread.start()
    中定义的当前线程中的流程进行操作
  • 实际上,您已经扩展了
    线程
    ,并实现了
    可运行
    。如果是这种情况,
    Runnable
    接口是冗余的,因为
    Thread
    也实现了这个接口。此外,如果要重写
    start
    方法,则应小心,因为如果要启动新线程,则需要调用super。至少出于这个原因,最好让类只实现
    Runnable
    ,而不是exend
    Thread
    。此外,如果只实现
    Runnable
    ,最好不要在名称中使用
    Thread
    这个词

假设
MyThread
只实现
Runnable
接口,那么第二个代码段就是要使用的正确模式
Thread.start()
链接到一个本机方法,该方法将启动一个新线程。然后,它将调用自己的
run()
,这将对其实例
Runnable
变量调用
run()
。在您的第二个代码片段中,这将是
MyThread
的一个实例,您的
Runnable

根据您提供的信息,第一个代码段将不会编译,除非:

  • 您已经自己实现了
    start
    方法。如果是这种情况,代码将不会启动新线程,并且只按照
    MyThread.start()
    中定义的当前线程中的流程进行操作
  • 实际上,您已经扩展了
    线程
    ,并实现了
    可运行
    。如果是这种情况,
    Runnable
    接口是冗余的,因为
    Thread
    也实现了这个接口。此外,如果要重写
    start
    方法,则应小心,因为如果要启动新线程,则需要调用super。至少出于这个原因,让一个类只实现
    
    
    MyThread t2 = new MyThread();
    new Thread(t2).start();
    
    class MyThread extends Thread
    
    new Thread(new MyThread()).start();
    
    public class MyThread extends Thread {
        public void run() {
            if (Thread.currentThread() != this) {
                System.out.println("Wrapped into a separate thread");
                start();
            } else {
                System.out.println("MyThread run as expected");
            }
        }
        public static void main(String[] args) {
            new Thread(new MyThread ()).start();
        }
    }        
    
    public class MyJPanel extends JPanel implements Runnable {
        public void run() {
            System.out.println("Hello MyJPanel");
        }
        public static void main(String[] args) {
            new Thread(new MyJPanel()).start();
        }
    }