title: cleaning up after using a SwingWorker
body: <p>NB This is not about terminating a worker thread.  It's about the aftermath of a normal termination.</p>
  
  <p>I'm calling <code>execute</code> in the EDT, so this spawns a "worker thread".<br>
  I'm calling <code>worker.get()</code> in a <code>Callable</code> which I submit to an <code>ExecutorService</code>, specifically a <code>ThreadPoolExecutor</code>.</p>
  
  <p>The task ends OK (i.e. <code>worker.get()</code> returns with a result, and the <code>Callable</code> also ends OK).</p>
  
  <p>I call <code>shutdown()</code> on the <code>Executor Service</code>: method terminates normally.</p>
  
  <p>The puzzle comes when I examine the threads after this.  This is in the context of unit testing, and I basically want to kill off all the activity which has been started during the last test.</p>
  
  <p>I'm listing all the threads, and in addition to the various ones which were present before the test started I see this:</p>
  
  <blockquote>
    <p># thread Thread[pool-2-thread-1,5,main], state WAITING, alive
    True, interrupted False, thread group main<br>   # thread
    Thread[SwingWorker-pool-4-thread-1,5,main], state WAITING, alive True,
    interrupted False, thread group main<br></p>
  </blockquote>
  
  <p>The trouble is, as the tests get run, the newly constructed "Application" object makes a new thread pool each time, and more and more <code>SwingWorkers</code> get created... and none of these threads appears to transition to the <code>Thread.State</code> "TERMINATED" (which presumably would mean they would then cease to be listed).</p>
  
  <p>I then tried calling <code>join</code> on the "SwingWorker-pool-4-thread" <code>Thread</code>... but this causes my current thread to hang.</p>
  
  <p>Can anyone explain what's going on here and how to transition these threads to "TERMINATED"?</p>
  
  <p><strong><em>later</em></strong></p>
  
  <p>Response to 2 helpful comments.  10 threads, right.  My thinking is just that a test if it fails (or an exception occurs) this can leave things in a troublesome state: suppose, in a functional test, 3 SWs are involved, and all sorts of <code>publish/process</code> stuff is going on, not to mention various <code>Runnable</code>s in the EDT.  Before moving to the next test I want everything to be shut, closed, ended, killed, returned to a pristine, virginal state! </p>
  
  <p>To ensure all <code>Runnable</code>s have ended we have <code>Robot.waitForIdle</code>(). I've also thought up a strategy for ensuring the <code>publish/process</code> thing has ended: <a href="https://stackoverflow.com/questions/24958793/swingworker-done-is-executed-before-process-calls-are-finished/35526033#35526033">SwingWorker, done() is executed before process() calls are finished</a>... . But in fact the latter, useful as it is, presupposes that the testing code <strong>knows</strong> which SWs to call the method on... I'm looking for a blunderbus, which will just kill em stone dead.</p>
  
  <p>The <code>toString</code> for these Thread objects shows clearly which has been created since starting the latest test... but I don't know how to kill 'em off.  Isn't it the case that "WAITING" means that, vampire-like, they might rise up again and do all sorts of bad things?  And just leaving vast numbers of "waiting" Threads hanging around, potentially running into their hundreds, seems a bit... untidy!</p>
  
  <p><strong><em>even later</em></strong></p>
  
  <p>Ah yes, getting hold of the <code>AppContext</code> object is vital because you need to "reset" this in order to prevent <code>RejectedExecutionException</code>.  See my answer for how to do in Jython.</p>
  
  <p>I also note that in the SW API doc it says </p>
  
  <blockquote>
    <p>Because SwingWorker implements Runnable, a SwingWorker can be
    submitted to an Executor for execution.</p>
  </blockquote>
  
  <p>This presumably means that you don't have to use SW's default executor at all.  Might be the way to go, but unless needed for another reason in the app code, it kind of violates the principle of not tailoring the app code for the convenience of the testing code...</p>