Java 中的“实现 Runnable”与“扩展线程”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/541487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"implements Runnable" vs "extends Thread" in Java
提问by user65374
From what time I've spent with threads in Java, I've found these two ways to write threads:
从我在 Java 中使用线程开始,我发现了以下两种编写线程的方法:
With implements Runnable
:
与implements Runnable
:
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call
Or, with extends Thread
:
或者,使用extends Thread
:
public class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
public void run() {
//Code
}
}
//Started with a "new MyThread().start()" call
Is there any significant difference in these two blocks of code ?
这两个代码块有什么显着差异吗?
采纳答案by Jon Skeet
Yes: implements Runnable
is the preferred way to do it, IMO. You're not really specialising the thread's behaviour. You're just giving it something to run. That means compositionis the philosophically"purer" way to go.
是的:Runnable
IMO 是首选的实现方式。您并没有真正专注于线程的行为。你只是给它一些东西来运行。这意味着组合是哲学上“更纯粹”的方式。
In practicalterms, it means you can implement Runnable
and extend from another class as well.
在实践方面,它意味着你可以实现Runnable
从另一个类扩展为好。
回答by Powerlord
I'm not an expert, but I can think of one reason to implement Runnable instead of extend Thread: Java only supports single inheritance, so you can only extend one class.
我不是专家,但我能想到一个原因,实现 Runnable 而不是扩展 Thread:Java 只支持单继承,所以你只能扩展一个类。
Edit: This originally said "Implementing an interface requires less resources." as well, but you need to create a new Thread instance either way, so this was wrong.
编辑:这最初是说“实现一个接口需要更少的资源”。同样,但是您需要以任何一种方式创建一个新的 Thread 实例,所以这是错误的。
回答by starblue
Instantiating an interface gives a cleaner separation between your code and the implementation of threads, so I'd prefer to implement Runnable in this case.
实例化接口可以更清晰地分离代码和线程的实现,因此在这种情况下我更愿意实现 Runnable。
回答by Bob Cross
tl;dr: implements Runnable is better. However, the caveat is important
tl;dr:实现 Runnable 更好。然而,警告很重要
In general, I would recommend using something like Runnable
rather than Thread
because it allows you to keep your work only loosely coupled with your choice of concurrency. For example, if you use a Runnable
and decide later on that this doesn't in fact require it's own Thread
, you can just call threadA.run().
一般来说,我会推荐使用类似Runnable
而不是Thread
因为它允许你的工作只与你选择的并发松散耦合。例如,如果您使用 aRunnable
并稍后决定这实际上并不需要它自己的Thread
,您可以调用 threadA.run()。
Caveat:Around here, I strongly discourage the use of raw Threads. I much prefer the use of Callablesand FutureTasks(From the javadoc: "A cancellable asynchronous computation"). The integration of timeouts, proper cancelling and the thread pooling of the modern concurrency support are all much more useful to me than piles of raw Threads.
警告:在这里,我强烈反对使用原始线程。我更喜欢使用Callables和FutureTasks(来自 javadoc:“一个可取消的异步计算”)。超时的集成、适当的取消和现代并发支持的线程池对我来说都比成堆的原始线程有用得多。
Follow-up:there is a FutureTask
constructorthat allows you to use Runnables (if that's what you are most comfortable with) and still get the benefit of the modern concurrency tools. To quote the javadoc:
后续:有一个FutureTask
构造函数允许您使用 Runnables(如果这是您最习惯的),并且仍然可以获得现代并发工具的好处。 引用 javadoc:
If you don't need a particular result, consider using constructions of the form:
如果您不需要特定结果,请考虑使用以下形式的构造:
Future<?> f = new FutureTask<Object>(runnable, null)
So, if we replace their runnable
with your threadA
, we get the following:
因此,如果我们将它们替换runnable
为您的threadA
,我们将得到以下信息:
new FutureTask<Object>(threadA, null)
Another option that allows you to stay closer to Runnables is a ThreadPoolExecutor. You can use the executemethod to pass in a Runnable to execute "the given task sometime in the future."
另一个让你更接近 Runnables 的选项是ThreadPoolExecutor。您可以使用execute方法传入 Runnable 以执行“将来某个时间的给定任务”。
If you'd like to try using a thread pool, the code fragment above would become something like the following (using the Executors.newCachedThreadPool()factory method):
如果您想尝试使用线程池,上面的代码片段将变成如下所示(使用Executors.newCachedThreadPool()工厂方法):
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());
回答by Fabian Steeg
You should implement Runnable, but if you are running on Java 5 or higher, you should not start it with new Thread
but use an ExecutorServiceinstead. For details see: How to implement simple threading in Java.
您应该实现 Runnable,但如果您在 Java 5 或更高版本上运行,则不应new Thread
使用ExecutorService来启动它。有关详细信息,请参阅:如何在 Java 中实现简单线程。
回答by Herms
One thing that I'm surprised hasn't been mentioned yet is that implementing Runnable
makes your class more flexible.
还没有提到让我感到惊讶的一件事是实现Runnable
使您的类更加灵活。
If you extend thread then the action you're doing is always going to be in a thread. However, if you implement Runnable
it doesn't have to be. You can run it in a thread, or pass it to some kind of executor service, or just pass it around as a task within a single threaded application (maybe to be run at a later time, but within the same thread). The options are a lot more open if you just use Runnable
than if you bind yourself to Thread
.
如果您扩展线程,那么您正在执行的操作将始终在线程中。但是,如果您实施Runnable
它,则不必如此。您可以在线程中运行它,或者将它传递给某种执行程序服务,或者只是将它作为单线程应用程序中的任务传递(可能稍后运行,但在同一线程中)。选项有很多更开放,如果你只需要使用Runnable
比如果你绑定自己Thread
。
回答by Govula Srinivas
Separating the Thread class from the Runnable implementation also avoids potential synchronization problems between the thread and the run() method. A separate Runnable generally gives greater flexibility in the way that runnable code is referenced and executed.
将 Thread 类与 Runnable 实现分离还避免了线程和 run() 方法之间潜在的同步问题。单独的 Runnable 通常在引用和执行可运行代码的方式上提供更大的灵活性。
回答by panzerschreck
Moral of the story:
故事的道德启示:
Inherit only if you want to override some behavior.
仅当您想覆盖某些行为时才继承。
Or rather it should be read as:
或者更确切地说,它应该被理解为:
Inherit less, interface more.
少继承,多接口。
回答by n13
Runnable because:
可运行,因为:
- Leaves more flexibility for the Runnable implementation to extend another class
- Separates the code from execution
- Allows you to run your runnable from a Thread Pool, the event thread, or in any other way in the future.
- 为 Runnable 实现提供更大的灵活性以扩展另一个类
- 将代码与执行分开
- 允许您从线程池、事件线程或将来以任何其他方式运行您的可运行对象。
Even if you don't need any of this now, you may in the future. Since there is no benefit to overriding Thread, Runnable is a better solution.
即使您现在不需要这些,将来也可能需要。由于覆盖 Thread 没有任何好处,Runnable 是一个更好的解决方案。
回答by Bart van Heukelom
I would say there is a third way:
我想说还有第三种方式:
public class Something {
public void justAnotherMethod() { ... }
}
new Thread(new Runnable() {
public void run() {
instanceOfSomething.justAnotherMethod();
}
}).start();
Maybe this is influenced a bit by my recent heavy usage of Javascript and Actionscript 3, but this way your class doesn't need to implement a pretty vague interface like Runnable
.
也许这有点受到我最近大量使用 Javascript 和 Actionscript 3 的影响,但是这样您的类就不需要实现像Runnable
.