Class BatchService<TK extends BatchServiceTask>
A pool-based thread execution service, that dynamically optimises its size.
This is a base class that allow you to manage the execution of a number of tasks in parallel.
 This is achieved by means of a thread pool, which of size is dynamically adjusted via PoolSizeTuner, 
 in order to optimise the task throughput (i.e., the number of tasks that complete their execution in the unit of time).
You should initialise this class with a moderate initial pool size (default is the number of available processors), cause the tuning algorithm works well (i.e. converges) when it approaches the best value from the left.
The theory says that the optimal number of threads is given by the number of available processors and the ratio between task waiting time and real CPU consumption time. However things can be more complicated when task latencies depend on how much they communicate or interfere each other, for instance by hitting transactions on the same database. This is the rationale to base thread optimisation on live performance measurement.
- date
- 8 Oct 2013
- Author:
- Marco Brandizi
- 
Nested Class SummaryNested ClassesModifier and TypeClassDescriptionprotected classThe customPoolSizeTunerthat is used to optimise this service.
- 
Field SummaryFieldsModifier and TypeFieldDescriptionprotected intThis should be 1 if there are multiple and different exit codes returned by submitted tasksBatchServiceTask.getExitCode().protected uk.org.lidalia.slf4jext.Loggerprotected PoolSizeTuner
- 
Constructor SummaryConstructorsConstructorDescriptionDefaults toRuntime.getRuntime().availableProcessors()BatchService(int initialThreadPoolSize) Initialises a pool service with this number of initial threads.
- 
Method SummaryModifier and TypeMethodDescriptionprotected voidfinalize()StopspoolSizeTuner.intlongThe no of completed tasks.intUsed to dynamically adjust the no. threads that the service runs in parallel.uk.org.lidalia.slf4jext.LevelThe submission of a new task is notified to the logging system via this level (Level.INFOby default).intprotected BatchService<TK>.BatchServiceTunerAllows you to initialise with a customBatchService<TK extends BatchServiceTask>.BatchServiceTuner.protected ExecutorServicenewThreadPoolExecutor(int initialThreadPoolSize) Allows you to initialise with a customExecutorService.voidsetSubmissionMsgLogLevel(uk.org.lidalia.slf4jext.Level submissionMsgLogLevel) voidsetThreadFactory(ThreadFactory threadFactory) It's like theThreadPoolExecutor.setThreadFactory(ThreadFactory)and might be useful here as well.voidsetThreadPoolSize(int threadPoolSize) voidSubmits a task into the pool, synchronising updates requested frompoolSizeTunerand other internal state information.voidThis can be used after you have submitted all the tasks that you have to run, when you want to wait that all of them complete their execution.
- 
Field Details- 
lastExitCodeprotected int lastExitCodeThis should be 1 if there are multiple and different exit codes returned by submitted tasksBatchServiceTask.getExitCode(). It should be a given value if all the submitted tasks returned that same value and it is non-zero. Should be 0 in all other cases.
- 
poolSizeTuner
- 
logprotected uk.org.lidalia.slf4jext.Logger log
 
- 
- 
Constructor Details- 
BatchServicepublic BatchService()Defaults toRuntime.getRuntime().availableProcessors()
- 
BatchServicepublic BatchService(int initialThreadPoolSize) Initialises a pool service with this number of initial threads.
 
- 
- 
Method Details- 
newPoolSizeTunerAllows you to initialise with a customBatchService<TK extends BatchServiceTask>.BatchServiceTuner. In most cases you will be fine with the default. If you need to change its tuning parameters, use thepoolSizeTunerfield. This is called by theBatchService(int)constructor (and all the others).
- 
newThreadPoolExecutorAllows you to initialise with a customExecutorService. WARNING: this class was designed and tested withfixed poolsin mind. This method is supposed to instantiate variants of fixed thread pools, in other to accommodate specific needs. One example is when you need to give different priorities to the tasks in a pool. We haveBatchServiceTask.TaskComparatorfor that, which can be instantiated from this method this way (method inspired to this)):return new ThreadPoolExecutor ( initialThreadPoolSize, initialThreadPoolSize, 0L, TimeUnit.MILLISECONDS, new PriorityBlockingQueue Use executors other than fixed pool size at your own risk!( initialThreadPoolSize, new BatchServiceTask.TaskComparator () ) ); - Parameters:
- initialThreadPoolSize- the initial thread pool size.
 
- 
submitSubmits a task into the pool, synchronising updates requested frompoolSizeTunerand other internal state information.
- 
waitAllFinishedpublic void waitAllFinished()This can be used after you have submitted all the tasks that you have to run, when you want to wait that all of them complete their execution. The method starts atimerthat reports the current state (with INFO log messages).
- 
getCompletedTaskspublic long getCompletedTasks()The no of completed tasks. This method is not synchronised, so you might get a number slightly lower than the real one.
- 
getPoolSizeTunerUsed to dynamically adjust the no. threads that the service runs in parallel. Most cases you will be fine with thedefault implementation of this. If not, you should set this field in a.invalid referenceconstructor
- 
getThreadPoolSizepublic int getThreadPoolSize()
- 
setThreadPoolSizepublic void setThreadPoolSize(int threadPoolSize) 
- 
getLastExitCodepublic int getLastExitCode()
- 
getBusyTaskspublic int getBusyTasks()
- 
getSubmissionMsgLogLevelpublic uk.org.lidalia.slf4jext.Level getSubmissionMsgLogLevel()The submission of a new task is notified to the logging system via this level (Level.INFOby default). If your application has very many tasks and you don't want to get bothered with these messages, you can change the log granularity here. If the level you set is disabled, this class will instead log anotificationfrom time to time.
- 
setSubmissionMsgLogLevelpublic void setSubmissionMsgLogLevel(uk.org.lidalia.slf4jext.Level submissionMsgLogLevel) 
- 
setThreadFactoryIt's like theThreadPoolExecutor.setThreadFactory(ThreadFactory)and might be useful here as well.
- 
finalizeStopspoolSizeTuner.
 
-