v1 Single-threaded v2 Threaded AbstractDispatchHandler v3 DailyDispatchHandler uses sleep() instead of a tight loop v4 Can be stopped and interrupted v5a Synchronization of dispatch() and makeVehicleAvailable() Given the current implementation, there isn't a deadlock problem because dispatch() doesn't "retry" (it returns false) v5b Synchronized collection rather than synchronized methods in Dispatcher v6a Have dispatch "retry" and fix the race condition with a call to wait() Acquire the monitor, call availableVehicles.size(), if not > 0 then wait() v6b Use a LinkedBlockingQueue NOT DONE YET v7/v8/v? Use an Executior and ThreadPool v?? Have the message actually sent using a thread (in case the communication itself is a performance bottleneck)