Well, how does a Thread get a connection? By calling a getConnection() method somewhere? Isn't that getConnection() code under your control? I'm guessing maybe it invokes wait() on some appropriate monitor object. You would need to consider - is there any way out or this? The user might call the interrupt() method I suppose - your getConnection() can handle this, maybe by batching the InterruptedException and de-scheduling the thread for a connection, then re-throw the InterruptedException so that the calling code can handle it however they want.
It's also possible the user might invoke deprecated methods like stop() or resume(). Of course, anything that goes wrong after that is their fault really.
But you might at least check the isAlive() method of a thread before you return a Connection to it. If the thread is already dead, de-schedule it and log a warning, since there's no apparent good reason for this to occur.
With careful coding you may be able to avoid needing a reaper thread - but it's not a bad idea to have one anyway as a back-up if you're not sure what weird things other coders might try to do with your code.