通过扩展Thread类或实现Runnable接口来创建线程,哪种方式更可取?

7
我想了解通过扩展线程类还是实现Runnable接口来创建线程更可取,为什么?谢谢。
4个回答

9
你应该将其变成Runnable,然后将其添加到任何现有的线程池类中。你正在将你的工作单元封装在新类中,然后使用线程来运行它。
只有在对线程类本身进行扩展时(例如用新功能扩展它)才会扩展Thread。我怀疑这不是这种情况。
另一种方法是创建一个新类,它是线程和自定义逻辑的组合,例如它内部有一个Thread,并且具有自己的“execute()”方法,在其中安排线程并将(this)作为工作项添加,完全隐藏在外部...但在这种情况下,您仍然会使您的类Runnable,只是提供了一个方便的方法来更轻松地将其添加到线程中。

2

如果您扩展线程(Thread),您总是需要调用.start(),它将启动一个新的线程并执行任务。

如果您将其设置为Runnable,则也可以使用new Thread(runnable).start(),但您不必局限于此。您可以回收线程,从而像这样节省一些资源:

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

首先将您的可运行对象放入一个列表中,然后在需要执行时再执行它们:

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);
}

或者你甚至可以这样做

runnable.run();

在你自己的线程中执行。

也许你甚至可以保存一个可运行的实例,在之后进行反序列化并运行它。
如果你扩展了线程,所有这些灵活性都将不存在。


1

实例化Runnable可以在您的代码和线程实现之间提供更清晰的分离。 Runnable接口仅说明您可以在不同的线程中运行此代码。

此外,由于您可以实现许多接口但只扩展一个类,因此只有在实现Runnable时才能提供自己的超类。如果您扩展Thread,则无法拥有任何其他超类。

Runnable的唯一注意事项是您需要两个对象:一个Thread实例以实际运行代码,另一个是您的Runnable实现对象以提供代码。


0

Runnable是因为你没有向Thread类添加专门的行为-你只是将你的逻辑标记为能够作为自己的线程运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接