Block thread or reject task when buffer is full

Prior to this commit, an attempt to execute a task when the ring buffer
was full would result in a TaskRejectedException being thrown. This
commit enhances RingBufferTaskExecutor so that its behavior in this
situation is configurable. It can either be configured to throw a
TaskRejectedException or to block the calling thread until there's
space in the ring buffer for the new task.