"implements Runnable" vs. "extends Thread"
From what time I've spent with threads in Java, I've found these two ways to write threads:
With implements Runnable
:
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call
Or, with 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 ?
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 composition is the philosophically "purer" way to go.
In practical terms, it means you can implement Runnable
and extend from another class as well.
tl;dr: implements Runnable is better. However, the caveat is important
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().
Caveat: Around here, I strongly discourage the use of raw Threads. I much prefer the use of Callables and 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.
Follow-up: there is a FutureTask
constructor that 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:
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:
new FutureTask<Object>(threadA, null)
Another option that allows you to stay closer to Runnables is a ThreadPoolExecutor. You can use the execute method to pass in a Runnable to execute "the given task sometime in the future."
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):
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());
Moral of the story:
Inherit only if you want to override some behavior.
Or rather it should be read as:
Inherit less, interface more.
链接地址: http://www.djcxy.com/p/2684.html上一篇: wait()和sleep()之间的区别
下一篇: “实现Runnable”与“扩展线程”