我想找出扩展Thread类的可能优点是什么?
这是我描述的另一个问题的一部分:在Java中有两种创建线程的方法
- 从线程类扩展的
- 实现可运行接口
使用Thread类而不是Runnable接口有什么优点吗?您知道有哪些类是从Thread类扩展而来的,然后如果用户想要多线程功能,就要求用户从这些类扩展吗?
public class ThreadExtended extends Thread{
//override some functions || add more functionality to Thread class
}
public class MyThread extends ThreadExtended{
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println("Using ThreadExtended instead of Thread directly");
}
}
public static void main(String args[])
{
MyThread myThread = new MyThread();
myThread.start();
}
}
很少有令人信服的理由来扩展Thread类。我会想象在大多数情况下,你最终会把所有的'do some stuff'逻辑扔到run方法中。
你绝对应该坚持实现Runnable。通过选择扩展Thread,您正在创建一个可能毫无意义的类层次结构,并且最终会限制您将来重构事物的选择。通过选择实现Runnable,您不需要实现者的血统是什么,并且您可以使用强大的抽象(如ExecutorService)来抽象运行代码块的具体细节。最后,选择实现一个接口而不是扩展一个类是一个很好的实践!
扩展Thread
的唯一原因是如果您需要添加与线程本身相关联的行为,而不是线程正在执行的任务。
例如,如果您正在实现一个线程池(没有人应该再这样做了,给定java.util.concurrent
),您需要更改线程的行为,以便(1)它可以接受新工作,(2)它将自己返回到线程池。以非常简单的形式:
public void setRunnable(Runnable runnable) {
this.runnable = runnable;
}
public void run() {
while (true) {
// wait on lock
try {
this.runnable.run();
}
catch (Throwable ex) {
// do something with exception
}
finally {
// return to pool
}
}
}
如果我也配置线程,我发现扩展线程更清楚,例如:
class FileReaper extends Thread {
FileReaper() {
setDaemon(true);
setName(getClass().getSimpleName());
}
@Override public void run() {
// do something
}
}
简单地说,当您扩展Thread时,它将是您将扩展的唯一类!
扩展Thread
还有一个很好的理由——如果你想创建一个loop Thread:
这是一个典型的loop线程实现的例子,使用prepare()和loop()的分离来创建一个初始处理程序来与loop通信。
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
UI线程是一个loop thread,但是你可能想要创建你自己的worker loop thread。要了解Looper
运行其loop()
方法的Thread
的行为,请参阅我最近的回答。