I have a card game app where the "Droid" hand has to choose among multiple discards to optimize its hand. So I am threading the possible discard choices and then calculating the hand valuation. I use two different approaches to hand valuation; one is exhaustive but can be very expensive, and the other is heuristic and very fast. I switch from the exhaustive approach to the heuristic approach once the computation time exceeds 500ms. I do this by starting the threads over the possible discards, and then also starting a sleep thread. When it finishes sleeping, it interrupts the other threads and I then rerun them with the heuristic approach. 

All of this is working fine.But in checking for an interrupted thread in the join loop, I immediately throw an `InterruptedException` so that the caller knows to rerun the calculation. In doing so, I don't ever join the *other* interrupted threads. Is that a resource leak, or will the other threads be cleaned up eventually?

Code snippets follow:
Starting my threads:

```
    for (Card disCard : cardsWithAdded) {
        CardList cards = new CardList(cardsWithAdded);
        cards.remove(disCard);

        testHand[iThread] = new ThreadedHand(this.hand.getRoundOf(), cards, disCard, this.method, isFinalTurn); //creates new hand with replaced cards
        t[iThread] = new Thread(threadGroup,testHand[iThread]);
        t[iThread].start(); //calls meldAndEvaluate
        iThread++;
    }

```

Interrupting them in the sleep thread:

```
        public void run() {
        final long sleepStartTime = System.currentTimeMillis();
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            // if interrupted, this means the other threads finished their work before the sleep ended
            return;
        }
        threadGroup.interrupt(); //interrupt the other calculation threads
    }

```

Check for interruption in the calculation thread (in a loop):

```
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }

```

Setting a flag in run:

```
        public void run()  {
        threadStart = System.currentTimeMillis();
        wasThreadInterrupted = false;
        try {
            this.meldAndEvaluate(this.method, EasyComputerPlayer.this , this.isFinalTurn);
        } catch (InterruptedException e) {
            //just break out of this thread
            threadStop = System.currentTimeMillis();
            wasThreadInterrupted = true;
        }
        threadStop = System.currentTimeMillis();
    }

```

And the join where I break at the first interrupted thread:

```
         for (int iThread=0; iThread < this.numThreads; iThread++) {
        try {
            t[iThread].join();
        } catch (InterruptedException e) {
            throw new InterruptedException(String.format("%s-%s: findBestHandFinish interrupted in join()...",FiveKings.APP_TAG,Thread.currentThread().getName()));
        }
        //can only test this flag after we've rejoined the thread to this one
        if (testHand[iThread].wasThreadInterrupted()) throw new InterruptedException(String.format("After join: Thread %s shows was-interrupted - throwing exception", t[iThread].getName()));

```