- tasks are still enqueued without reading the clock
- in order to be resilient against timer thread over-sleeping the tasks
are passed to the timer thread using an AbstractNodeQueue and the
wheel itself is now private to the timer thread
- reuse queue Nodes along the way to minimize allocation costs
The problem with the old implementation was that the timer thread could
sleep too long, then wake up and run multiple buckets in quick
succession. Tasks enqueued just before that event could then get
executed basically immediately, i.e. before their allotted time.