Java 这两种启动线程的方法有什么区别?
如果我有一个实现Runnable接口的类,那么main方法中这些语句之间的区别是什么Java 这两种启动线程的方法有什么区别?,java,concurrency,multithreading,Java,Concurrency,Multithreading,如果我有一个实现Runnable接口的类,那么main方法中这些语句之间的区别是什么 MyThread t1 = new MyThread(); t1.start(); 及 第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个新线程来运行Runnable的run()方法。第一个调用(如果是run())将在当前线程中执行,而第二个调用将创建一个运行run()的新线程方法。在第二个方法中,您创建了一个不包含在变量中的新线程,并启动这个新线程。t2保持不变 在第一个中,您创建t1
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
方法,则应小心,因为如果要启动新线程,则需要调用super。至少出于这个原因,最好让类只实现start
,而不是exendRunnable
。此外,如果只实现Thread
,最好不要在名称中使用Runnable
这个词Thread
MyThread
只实现Runnable
接口,那么第二个代码段就是要使用的正确模式Thread.start()
链接到一个本机方法,该方法将启动一个新线程。然后,它将调用自己的run()
,这将对其实例Runnable
变量调用run()
。在您的第二个代码片段中,这将是MyThread
的一个实例,您的Runnable
根据您提供的信息,第一个代码段将不会编译,除非:
- 您已经自己实现了
方法。如果是这种情况,代码将不会启动新线程,并且只按照start
中定义的当前线程中的流程进行操作MyThread.start()
- 实际上,您已经扩展了
,并实现了线程
。如果是这种情况,可运行
接口是冗余的,因为Runnable
也实现了这个接口。此外,如果要重写Thread
方法,则应小心,因为如果要启动新线程,则需要调用super。至少出于这个原因,让一个类只实现start
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(); } }