Move a handful of operations outside critical sections

These operations don't need to be in the critical section.

It may make a difference in some of the microbenchmarks that stress
the interlock...it's hard to tell for sure because they tend to bounce
around quite a bit in this test.
Avoid some Goroutine leaks

Noticed when doing extended BenchmarkStartup testing.

The leaks fixed are all a variant of goroutines getting stuck on token
bucket manipulation, and so all these code paths have learned an
early-exit when the 'finalize' channel is closed.

After fixing the leaks, I noticed the asynchronicity of .Close() still
made testing the sum overhead of creation *and* destruction of a
Client value intractable, so .Close() has been made synchronous.  This
backpressure seems like a good idea to avoid overwhelming the garbage
collector and goroutine scheduler, and someone can re-introduce
asynchronicity in the case where that seems better.

The addition of the WaitGroup to make .Close() synchronous also seems
to be able to trigger the Go deadlock detector in some cases where a
leak would otherwise occur.