Java 什么';启动线程的不同方式有什么区别?
我有一个名为Java 什么';启动线程的不同方式有什么区别?,java,multithreading,Java,Multithreading,我有一个名为MyThread的类,它扩展了Thread类并实现了run()函数。当我想运行它时,我有两种方法: 新建实例并调用函数,如:newmythread().start() 新建一个实例,将实例作为参数传递给线程的构造函数,然后调用线程的start函数。如下所示:(新线程(新MyThread)).start() 任何人都能分辨出两者的区别吗?因为你说过你的类扩展了线程,第二个有点多余。在您的第二个示例中,您并没有将类用作,而是将其用作 通常,您要么扩展线程,然后调用它自己的开始(您的#1)
MyThread
的类,它扩展了Thread类并实现了run()
函数。当我想运行它时,我有两种方法:
newmythread().start()
(新线程(新MyThread)).start()代码>
任何人都能分辨出两者的区别吗?因为你说过你的类扩展了
线程,第二个有点多余。在您的第二个示例中,您并没有将类用作,而是将其用作
通常,您要么扩展线程
,然后调用它自己的开始
(您的#1),要么实现可运行
,然后使用线程
运行它(您的#2)。但是您不会扩展线程
,然后使用另一个线程
来运行它
就区别而言,如果您需要执行任何操作来控制或查询线程,那么在第一种情况下,您将在类的实例上使用thread
方法;在第二种情况下,您将在使用newthread
创建的实例上使用它们。如果扩展Thread
,但通过#2运行它,那么实例上的Thread
方法是不相关的,可能会令人困惑
最后一点通过示例可能更清楚:
扩展线程的示例:
class Foo extends Thread {
public void run() {
// ...
}
}
// Create it
Foo foo = new Foo();
// Start it
foo.start();
// Wait for it to finish (for example)
foo.join();
注意,我们通过foo
引用启动并连接了线程
实现Runnable
的示例:
class Foo implements Runnable {
public void run() {
// ...
}
}
// Create it
Foo foo = new Foo();
// Create a Thread to run it
Thread thread = new Thread(foo);
// Start it
thread.start();
// Wait for it to finish (for example)
thread.join();
注意:我们通过线程
引用启动并连接线程
不要这样做:
…因为现在在foo
和Thread
上都有Thread#join
;哪个是正确的?(答案是:thread
上的一个,但是它很混乱,所以最好不要这样做。)您正在传递的MyThread
实例只是充当Runnable
而不是单独的线程
这两种方式在逻辑上基本没有区别:
Thread
在start()
上执行的内部操作是调用Runnable的run()
方法
PThread pThread = new PThread(args);
Thread t = new Thread(pThread);
// allowed as pThread is extending Thread and hence,
//an implementation of Runnable
t.start();
当您执行新线程(new MyThread()).start()
时,您只是多余的,因为线程本身实现了可运行
但是,由于新线程将调用MyThread
的run() 那么,您有两种方法来实现多线程
扩展Thread
并使用newmythreand().start()
启动线程
实现Runnable
接口。在这种情况下,您可以使用(新线程(新MyThread)).start()
;开始一个线程
有关详细信息,请参阅(新线程(新MyThread)).start()
每个线程实现Runnable;在这种情况下,MyThread实例用作Runnable,新线程调用MyThread实现的run方法。您将无法使用MyThread停止线程(或通过任何方式控制它)。您不应该这样做。创建线程确实会更改一些变量,如ThreadGroup
中的“未启动线程数”
虽然它不应该引起问题,但它的风格不好,会让人困惑(“他为什么这么做?一定有很好的理由!”)。启动线程的方式(实现Runnable或扩展Thread类的类)
这只是您应用的抽象,注意(Runnable对象更一般,因为Runnable对象可以为类而不是线程创建子类)
良好的编码实践。
In both of the cases Thread.start() will called
如果您的类本身扩展了线程
,您可以按照第一种方法操作:
MyThread myThread = new MyThread();
myThread.start();
如果查看,您将看到第二种方法针对的是(仅)实现Runnable
(这意味着您的类只需要实现run()
方法)的类
区别在于Runnable
只是一个接口,而Thread
是一个类。这意味着,如果您希望将逻辑作为类的一部分,而该类出于某种原因需要扩展另一个类,那么您仍然可以实现可运行
,并使用第二种方法。线程本身就是可运行
的实现。当创建并启动线程的实例时,它将执行自己的run()
方法。如果将非null的Runnable target
指定给它的构造函数,那么它将调用它的目标的run()
方法,这从Thread
类的实现的run()
方法中可以明显看出:
@Override
public void run() {
if (target != null) {
target.run();
}
}
创建新执行线程的两种方法:
第一个是将类(即PThread
)声明为Thread
的子类:PThread扩展PThread
,并应重写class
Thread的run
方法。然后,我们可以轻松创建该类的实例化,并在其上调用start()
:
PThread pThread = new PThread(args);
pThread.start();
第二个是声明一个实现Runnable
接口的类:RThread实现Runnable
,然后实现run
方法。我们必须实例化RThread
并将其作为Runnable
目标传递给Thread
实例:
RunThread rThread = new RunThread(args); // args constructor argument if required
Thread t = new Thread(rThread);
t.start();
从上面启动线程的方法可以看出,实际上允许将扩展线程的类(例如PThread
)作为Runn传递给新的thread
构造函数
RunThread rThread = new RunThread(args); // args constructor argument if required
Thread t = new Thread(rThread);
t.start();
PThread pThread = new PThread(args);
Thread t = new Thread(pThread);
// allowed as pThread is extending Thread and hence,
//an implementation of Runnable
t.start();