Custom EventLoop scheduling and EventLoop metrics

Motivation:

Currently Channels are assigned to EventLoops by a round-robin like algorithm: EventLoops are assigned sequentially and begin again at the start in a circular manner. This approach may not always be ideal, especially when an application handles different types of connections (e.g. long-living and short-living).

Modifications:

Introduce two new interfaces: EventLoopScheduler and EventLoopMetrics. The EventLoopScheduler interface allows a user to provide his own implementation of EventLoopGroup.next(). The default implementation remains round-robin. The (Nio|Epoll)EventLoops now support to collect information about them. This is done via the EventLoopMetrics interface. This information can also be used by an EventLoopScheduler implementation to influence scheduling.

Result:

1) Users can plug in their own algorithms into NioEventLoopGroup and EpollEventLoopGroup. 2) Users can gather information from EventLoops and use the information in their custom EventLoopScheduler implementations.