I'm not a concurrency expert and you won't find anything terribly profound if you consider yourself an experienced multithreaded developer. But I did want to share a simple, basic tip for beginners. Often when a beginner decides that threads are the solution to whatever problem he's facing, he extends Thread. When told that extending Thread is a bad idea and that he should implement Runnable instead, it often falls on deaf ears. Most of the reasoning given is that there's no point in extending Thread and that you use up your one extension for no gain. This is all true but not entirely compelling. This morning I ran across a much more compelling argument: restarting a thread.
Threads, once stopped, can not be restarted so you have to create a new Thread and start that one. Normally even this may not be that big of a deal. But in this particular case this morning, the developer had state he wanted to preserve. Since his Thread could not be restarted, he'd have to create a new Thread, copy over that state, then start the new one. If he'd just used a Runnable, he could have simply started a new Thread with that Runnable and be done. Faced with that realization, he changed his code to use Runnables instead and is now a happy camper.

So, again, don't extend Thread. You gain nothing from it and tie your hands in more than one way.