从我在Java中使用线程所花费的时间来看,我发现了两种编写线程的方法:
使用Runnable**:**实现
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call或者,使用扩展
public class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
public void run() {
//Code
}
}
//Started with a "new MyThread().start()" call这两个代码块有什么显著的区别吗?
发布于 2009-02-12 14:32:54
是的:实现Runnable是最好的方法,海事组织。你并不是在专门研究线程的行为。你只是给了它一些东西去跑。这意味着作文是哲学上“纯粹”的方式。
实际上,它意味着您可以实现Runnable并从另一个类扩展.您还可以通过lambda表达式实现Runnable,从Java 8开始。
发布于 2009-02-12 14:37:05
tl;dr:实现Runnable更好。然而,警告是重要的。
通常,我建议使用类似于Runnable而不是Thread的东西,因为它允许您将工作与您选择的并发性松散地结合在一起。例如,如果您使用Runnable并在稍后决定这实际上不需要它自己的Thread,则只需调用threadA.run()即可。
警告:这里的,我强烈反对使用原始线程。我更喜欢使用可调用和FutureTasks (来自javadoc:“可取消的异步计算”)。超时的集成、适当的取消和现代并发支持的线程池对我来说都比成堆的原始线程更有用。
后续:有一个构造函数,它允许您使用Runnable(如果这是您最满意的地方),并且仍然可以从现代并发工具中获益。引用javadoc
如果不需要特定的结果,请考虑使用表单的构造:
Future<?> f = new FutureTask<Object>(runnable, null)因此,如果我们用您的runnable替换他们的threadA,我们会得到以下内容:
new FutureTask<Object>(threadA, null)另一个允许您更接近Runnables的选项是一个ThreadPoolExecutor。您可以使用执行方法传入一个Runnable,以执行“将来某个时候给定的任务”。
如果您想尝试使用线程池,那么上面的代码片段将变成如下所示(使用Executors.newCachedThreadPool()工厂方法):
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());发布于 2010-03-11 15:50:54
故事的寓意:
只有当您想要覆盖某些行为时才继承。
或者更确切地说,它应理解为:
继承少,界面多。
https://stackoverflow.com/questions/541487
复制相似问题