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

时间:2010-03-02 21:00:49

标签: java multithreading

我想知道哪个更适合通过扩展线程类或通过实现Runnable接口来创建线程。为什么?

谢谢..

4 个答案:

答案 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类添加专门的行为 - 你只是将你的逻辑标记为能够作为自己的线程运行。