Technicallly, a thread doesn't call your runnable (or callable) task directly. Instead, the threads in the pool are running internal code, which are used to extract your tasks from the queue, and call your task's run() method. Once your tasks return from the run() method, the internal code will fetch the next task (or wait is there are no more tasks).
There are no thread restarts. And threads are *not* being reused.