我想知道哪个更适合通过扩展线程类或通过实现Runnable接口来创建线程。为什么?
谢谢..
答案 0 :(得分:9)
您应该将其设为Runnable
,然后将其添加到任何现有的线程池类中。您正在将您的工作单元封装在新类中,然后使用线程来运行它。
如果您正在对线程类本身执行某些操作,则只会扩展Thread
,例如使用新功能扩展它。我怀疑是这样的。
另一种方法是创建一个由线程和自定义逻辑组成的新类,例如:它有一个Thread
内部和它自己的'execute()'方法,它调度线程并添加(this)作为工作项,完全隐藏在外面......但在这种情况下,你将成为你的无论如何,类Runnable
,只是提供一种方便的方法,使其更容易添加到线程中。
答案 1 :(得分:2)
如果你扩展Thread,你总是必须调用.start(),它启动一个新线程,并执行任务。
如果你使它成为Runnable,你也可以做新的Thread(runnable).start(),但你并不局限于此。您可以回收线程,从而节省一些资源:
ExecutorService recycleSingleThread = Executors.newSingleThreadExecutor();
service.execute(runnable);
service.execute(someOtherTask);
首先将一堆runnable放入列表中,然后在执行它们时执行它们:
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,然后将其反序列化并运行它 如果您扩展Thread,那么所有这些灵活性都不会出现。
答案 2 :(得分:1)
实例化Runnable可以更清晰地分离代码和线程的实现。 Runnable接口只是声明您可以在不同的线程中运行此代码。
此外,由于您可以实现许多接口但只扩展一个类,因此如果实现Runnable,则只能提供自己的超类。如果扩展Thread,则不能有任何其他超类。
Runnable唯一需要注意的是,你需要两个对象,一个是实际运行代码的Thread实例,另一个是Runnable实现来提供代码。
答案 3 :(得分:0)
Runnable,因为你没有向Thread类添加专门的行为 - 你只是将你的逻辑标记为能够作为自己的线程运行。