It seems to me that the only explanation for QPID-3872 is a publication issue.
At the minute, reads of members _dispatcher and _dispatcherThread are not thread safe and therefore a thread could read a stale values.
It appears that is what has happened in QPID-3872. The dispatcher thread was running run(), it called #dispatch() which first checked whether the _dispatcher member is non-null. In our failing case, the _dispatcher member was null. This could not normally be the case as _dispatcher is assigned before the Dispatcher thread is created (in startDispatcherIfNecessary).
I'm suggest changing _dispatcher and _dispatcherThread to volatile. The synchronisation within startDispatcherIfNecessary() should remain. The setters setDispatcherThread and setDispatcher are unused and should be removed.