我想了解通过扩展线程类还是实现Runnable接口来创建线程更可取,为什么?谢谢。
Runnable
,然后将其添加到任何现有的线程池类中。你正在将你的工作单元封装在新类中,然后使用线程来运行它。Thread
。我怀疑这不是这种情况。Thread
,并且具有自己的“execute()”方法,在其中安排线程并将(this)作为工作项添加,完全隐藏在外部...但在这种情况下,您仍然会使您的类Runnable
,只是提供了一个方便的方法来更轻松地将其添加到线程中。如果您扩展线程(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();
在你自己的线程中执行。
也许你甚至可以保存一个可运行的实例,在之后进行反序列化并运行它。
如果你扩展了线程,所有这些灵活性都将不存在。
实例化Runnable可以在您的代码和线程实现之间提供更清晰的分离。 Runnable接口仅说明您可以在不同的线程中运行此代码。
此外,由于您可以实现许多接口但只扩展一个类,因此只有在实现Runnable时才能提供自己的超类。如果您扩展Thread,则无法拥有任何其他超类。
Runnable的唯一注意事项是您需要两个对象:一个Thread实例以实际运行代码,另一个是您的Runnable实现对象以提供代码。
Runnable是因为你没有向Thread类添加专门的行为-你只是将你的逻辑标记为能够作为自己的线程运行。