Description
When there is only one service and the service is being activated and deactivated repetitively, ScheduledThreadPoolExecutor keeps being created and destructed by IdleStatusChecker, which causes big overhead. This becomes a real problem when a user uses a Connector to maintain just one connection, which is opened and closed very frequently, because the activation and the deactivation of the service follows the creation and the destruction of a session.
The solution is make the life cycle of IdleStatusChecker thread to follow the life cycle of respective services. For now, IdleStatusChecker is a singleton and manages threads by itself. By moving all thread management code to AbstractIoService, IdleStatusChecker doesn't need to start and stop thread excessively but AbstractIoService will stop the thread when dispose() is called explicitly by user, like other worker threads.
Done.