A helper for concurrency testing. One or more {@code TestThread} instances are instantiatedin a test with reference to the same "lock-like object", and then their interactions with that object are choreographed via the various methods on this class.
A "lock-like object" is really any object that may be used for concurrency control. If the {@link #callAndAssertBlocks} method is ever called in a test, the lock-like object must have amethod equivalent to {@link java.util.concurrent.locks.ReentrantLock#hasQueuedThread(Thread)}. If the {@link #callAndAssertWaits} method is ever called in a test, the lock-like object must have amethod equivalent to {@link java.util.concurrent.locks.ReentrantLock#hasWaiters(java.util.concurrent.locks.Condition)}, except that the method parameter must accept whatever condition-like object is passed into {@code callAndAssertWaits} by the test.
@param < L> the type of the lock-like object to be used
@author Justin T. Sampson