2

Code:

//List all threads:
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
System.out.println(runningThreads.toString());

//Thread creation:
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(this);

//Thread termination:
executorService.shutdownNow();

//List all threads:
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
System.out.println(runningThreads.toString());

I would expect the list that gets printed out to be exactly the same both times but what I'm getting is a print out of the thread that was created included in the results

How do I completely destroy a thread so that it's nowhere to be found?

Hooli
  • 1,135
  • 3
  • 19
  • 46
  • You should wait for the completion of shut down process. The threads may not be terminated yet. – glee8e Dec 15 '16 at 14:20

1 Answers1

1

shutdownNow() attempts to stop the running thread, but as its API documentation says:

This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

So the thread may still be running when the code after the call to shutdownNow() returns. Note also that you need to make sure that the task running in the thread actually terminates; shutdownNow() is not going to kill the thread, it will just try to interrupt it.

As the documentation says, call executorService.awaitTermination(...) after calling shutdownNow() to wait until the thread has stopped.

Jesper
  • 202,709
  • 46
  • 318
  • 350
  • What if it never terminates? It seems even if I put `awaitTermination` for days, it will just hang and never actually kill the thread – Hooli Dec 15 '16 at 14:29
  • 1
    @Hooli: you never show the task that you're submitting to the executor. if it doesn't quit in response to interruption (eats the InterruptedException and keeps on looping, or blocked on I/O) then it won't terminate. – Nathan Hughes Dec 15 '16 at 14:32
  • @NathanHughes: Would it be a good idea to change my thread from `while (true) {...}` to `while (!this.isInterrupted()) {...}`? – Hooli Dec 15 '16 at 14:34
  • @Hooli: not `this.isInterrupted`, you want `!Thread.currentThread().isInterrupted()`. but you also have to make sure the interrupted flag is set at that point; throwing InterruptedException clears the interrupted flag. but if you think you can do `this.isInterrupted()` it sounds like you're passing a Thread into the executorService. which is bad, it should be a Runnable or Callable. – Nathan Hughes Dec 15 '16 at 14:35
  • @NathanHughes: Any ideas on how to get around the `InterruptedException` when calling `executorService.awaitTermination` after interrupting a thread? (if `awaitTermination` is in a `try-catch`) – Hooli Dec 15 '16 at 15:40
  • I got around this by using my own `Boolean` instead of `.interrupt()` – Hooli Dec 15 '16 at 16:00
  • @Hooli you need a `volatile` Boolean, or an `AtomicBoolean`, not a plain `Boolean`, for visibility reasons. – GPI Dec 15 '16 at 16:33
  • @GPI: What do you mean? Do you have a link to explain in more detail? – Hooli Dec 15 '16 at 19:10
  • 2
    All data that is shared between threads need to be memory-synchronized. See: http://stackoverflow.com/a/106787/179850 – Gray Dec 15 '16 at 21:32