关于java:通过扩展Thread类或实现Runnable来创建线程更合适?

What is more advisable to create a thread by extending a Thread class or implementing Runnable?

本问题已经有最佳答案,请猛点这里访问。

我想知道,通过扩展线程类或实现可运行接口来创建线程,哪个更可取。为什么呢?

谢谢。。


您应该使它成为Runnable,然后将它添加到任何现有的线程池类中。您将工作单元封装在新类中,然后使用线程来运行它。

如果您对线程类本身做了一些事情,比如用新的功能扩展它,那么只会扩展Thread。我怀疑是这样。

另一种选择是创建一个由线程和自定义逻辑组成的新类,例如,它在内部有一个Thread和它自己的'execute()'方法,在其中调度线程并将(这个)添加为一个工作项,完全从外部隐藏…但在这种情况下,您将使您的类Runnable无论如何,只是提供了一个方便的方法,使添加到线程更容易。


如果扩展线程,则始终必须调用.start(),它将启动一个新线程并执行任务。

如果使其可运行,也可以执行新线程(runnable).start(),但不局限于此。您可以回收线程,从而节省一些这样的资源:

1
2
3
ExecutorService recycleSingleThread = Executors.newSingleThreadExecutor();
service.execute(runnable);
service.execute(someOtherTask);

先把一堆你的runnables放在一个列表中,然后在你想执行它们时执行它们:

1
2
3
4
5
6
7
8
9
10
11
List<Runnable> todoList = new ArrayList<Runnable>();
Runnable fetchPaper = new Runnable("paper");
todoList.add(fetchPaper);
Runnable fetchMilk = new Runnable("milk");
todoList.add(fetchMilk);

//do something else or even return todoList...
ExecutorService recycleSingleThread = Executors.newSingleThreadExecutor();
for(Runnable task : todoList){
    recycleSingleThread.execute(task);
}

或者你也可以

1
runnable.run();

在你自己的线内。

也许您甚至可以保存一个可运行的,然后反序列化并运行它。如果您要扩展线程,那么所有这些灵活性都将不存在。


实例化runnable可以在代码和线程实现之间实现更清晰的分离。可运行接口简单地声明您可以在不同的线程中运行此代码。

此外,由于可以实现多个接口,但只能扩展一个类,因此只有实现可运行时才能提供自己的超类。如果扩展线程,则不能有任何其他超类。

runnable唯一需要注意的是,您需要两个对象,一个线程实例来实际运行代码,另一个实现runnable来提供代码。


可运行,因为您没有向线程类添加专门的行为——您只是将逻辑标记为能够作为自己的线程运行。