Multiple Blockers
Interrupting a thread can require more than one technique if a thread can be blocked in multiple places. For example, some threads might sometimes be waiting on a monitor and other times on a socket. The interrupt() method must then interrupt both. The run() method must be written to ensure that interrupts cause the method to exit and not block again.
The hardest part of writing an interrupt can be inspecting all the code invoked from the thread's run() method and determining whether it can block and, if so, how to interrupt it. This is particularly hard if that method uses third-party code or libraries that don't clearly document their behavior or dependencies. Although I did not encounter this, it is easy to imagine library calls that are written so as to be essentially uninterruptible. Indeed, adding this kind of thread-specific behavioral information to signatures hints at potentially big requirement changes for those writing reusable code.
Interrupt Before Run
Again, an Interruptible scheduled to run via ThreadManager is guaranteed to have both its run() and interrupt() methods called, but not necessarily in that order. It turns out this is often easier to code correctly than you might think. For example, if a socket connection is open before run() is called, then interrupt() can safely close it; the run() method will find it closed when it is invoked and immediately exit.
Other times, however, interrupt() will have to set a special flag to let run() know that interrupt() has already been called and to avoid proceeding to any blocking code. The first time I got this wrong (I didn't have the flag logic), I briefly considered making a guarantee that run() was always invoked first.
However, what kind of guarantee could I really make? I could have interrupt() block until the runThread had started, but that wasn't sufficient. The thread might start but yield before the first instruction in the run() method, so interrupt() could still be called earlier than expected. The only way to guarantee that run() had accomplished any particular amount of work before interrupt() was called is with synchronization code (wait and notify, for example) inside cooperating run() and interrupt() methods. You can write such code if appropriate, but ThreadManager doesn't have this kind of knowledge and won't do it for you.