Interface ThreadPoolFactory
- All Known Implementing Classes:
AbstractThreadPoolFactory
,DefaultThreadPoolFactory
The factory allowing to get a thread pool (ExecutorService) for processing some AlgART array.
The object, implementing this interface, should be used when you need to
process some AlgART array ("source array") in several parallel threads
to improve performance on the multiprocessor systems.
In this case, you should split the algorithm into several tasks, where each task
calculates a part of the result (usually processes a region of the source array).
Then you need to call getThreadPool(sourceArray, someThreadFactory)
method of this object, submit all your tasks to the returned thread pool,
wait until all tasks will be completed (for example, by Future.get method)
and, at the end, call releaseThreadPool(ExecutorService)
method
to finish working with the thread pool.
The number of tasks, which your algorithm is split into, should be
equal to the result of recommendedNumberOfTasks(sourceArray)
method of this object. Note: if this number is 1, you should ignore multithreading and
perform the task in the current thread.
The technique described above can be automated by
performTasks(java.util.concurrent.ThreadFactory, Runnable[])
method.
We recommend to pass some instance of this interface to every algorithm
using multithreading technique to optimize performance on multiprocessor computers.
Then the application will be able to call algorithms with
a custom implementations of this interface, which controls the number of threads
and, maybe, supports a global application thread pool.
In particular, an instance of this interface can be passed to the standard
Arrays.copy(ArrayContext, UpdatableArray, Array)
method
via the custom implementation of ArrayContext
interface.
There is a simple default implementation of this interface:
DefaultThreadPoolFactory
.
- Author:
- Daniel Alievsky
-
Method Summary
Modifier and TypeMethodDescriptiongetThreadPool
(ThreadFactory threadFactory) Returns the thread pool that should be used for multithreading processing large data.getThreadPool
(Array sourceArray, ThreadFactory threadFactory) Returns the thread pool that should be used for multithreading processing an AlgART array.void
performTasks
(Runnable[] tasks) Equivalent toperformTasks
(null, tasks) call.void
performTasks
(Runnable[] tasks, int from, int to) Equivalent toperformTasks
(java.util.Arrays.copyOfRange(tasks, from, to)) call.void
performTasks
(ThreadFactory threadFactory, Runnable[] tasks) Performs the specified tasks by the thread pool, returned bygetThreadPool(threadFactory)
method in the beginning of execution.void
performTasks
(ThreadFactory threadFactory, Runnable[] tasks, int from, int to) Equivalent toperformTasks
(threadFactory, java.util.Arrays.copyOfRange(tasks, from, to)) call.void
performTasks
(Array sourceArray, ThreadFactory threadFactory, Runnable[] tasks) Equivalent toperformTasks(java.util.concurrent.ThreadFactory, Runnable[])
method with the only difference, that the thread pool is got viagetThreadPool(sourceArray, threadFactory)
method.int
Returns the recommended number of tasks, which your algorithm is split into for optimizing processing large data.int
recommendedNumberOfTasks
(Array sourceArray) Returns the recommended number of tasks, which your algorithm is split into for optimizing processing the given AlgART on multiprocessor computers.void
Finishes using the thread pool returned bygetThreadPool(Array, ThreadFactory)
method.Returns new factory, identical to this one with the only exception that the recommended number of tasks in the created instance is always one.
-
Method Details
-
recommendedNumberOfTasks
int recommendedNumberOfTasks()Returns the recommended number of tasks, which your algorithm is split into for optimizing processing large data. The returned value can be equal (or depend on) the result ofArrays.SystemSettings.availableProcessors()
, or can be specified in some system property or environment variable.The returned value is always positive.
- Returns:
- the recommended number of parallel tasks to perform the processing (>0).
-
recommendedNumberOfTasks
Returns the recommended number of tasks, which your algorithm is split into for optimizing processing the given AlgART on multiprocessor computers. The returned value can be equal (or depend on) the result ofArrays.SystemSettings.availableProcessors()
, or can be specified in some system property or environment variable. For little arrays, that are usually processed very quickly, we recommend to return 1 regardless of the number of processors.The returned value is always positive.
- Parameters:
sourceArray
- some AlgART array that should be processed.- Returns:
- the recommended number of parallel tasks to perform the processing (>0).
- Throws:
NullPointerException
- if the argument is null (not necessary).
-
singleThreadVersion
ThreadPoolFactory singleThreadVersion()Returns new factory, identical to this one with the only exception that the recommended number of tasks in the created instance is always one. More precisely, therecommendedNumberOfTasks()
andrecommendedNumberOfTasks(Array)
methods in the created factory always return 1, and all other methods are strictly equivalent to the corresponding methods of this instance.- Returns:
- the single-thread version of this factory.
-
getThreadPool
Returns the thread pool that should be used for multithreading processing large data. Depending on implementation, this method may either create a new thread pool, or return some already existing pool, for example, the global thread pool of the application. In any case, you must call, in a finally section, thereleaseThreadPool(ExecutorService)
method for this pool after finishing your algorithm.The threadFactory can be used for creation new thread pool. This argument may be null: in this case, some default thread factory should be used.
- Parameters:
threadFactory
- if not null, specifies the desired thread factory for using by the thread pool.- Returns:
- the thread pool for parallel processing large data.
-
getThreadPool
Returns the thread pool that should be used for multithreading processing an AlgART array. Depending on implementation, this method may either create a new thread pool, or return some already existing pool, for example, the global thread pool of the application. In any case, you must call, in a finally section, thereleaseThreadPool(ExecutorService)
method for this pool after finishing your algorithm.The threadFactory may be used for creation new thread pool. This argument may be null: in this case, some default thread factory should be used.
- Parameters:
sourceArray
- some AlgART array that should be processed.threadFactory
- if not null, specifies the desired thread factory for using by the thread pool.- Returns:
- the thread pool for parallel processing the array.
- Throws:
NullPointerException
- if sourceArray argument is null (not necessary).
-
releaseThreadPool
Finishes using the thread pool returned bygetThreadPool(Array, ThreadFactory)
method. This method must be called in a finally section after finishing usage of the pool. The reason is that if the implementation ofgetThreadPool(Array, ThreadFactory)
method has created a new thread pool, this method probably calls its shutdown method to remove extra system threads.- Parameters:
pool
- the thread pool created by the previousgetThreadPool(Array, ThreadFactory)
call.- Throws:
NullPointerException
- if the argument is null (not necessary).
-
performTasks
Equivalent toperformTasks
(null, tasks) call.- Parameters:
tasks
- the tasks which should be performed.- Throws:
NullPointerException
- if tasks argument or one of the tasks is null.
-
performTasks
Performs the specified tasks by the thread pool, returned bygetThreadPool(threadFactory)
method in the beginning of execution.More precisely, if tasks.length==0, this method does nothing, if tasks.length==1, this method just calls tasks[0].run(), and if tasks.length>1, the tasks are performed by the following code (where pool is the result of
getThreadPool(threadFactory)
call):Future<?>[] results = new Future<?>[tasks.length]; for (int threadIndex = 0; threadIndex < tasks.length; threadIndex++) { results[threadIndex] = pool.submit(tasks[threadIndex]); } try { for (int threadIndex = 0; threadIndex < tasks.length; threadIndex++) { results[threadIndex].get(); // waiting for finishing } } catch (ExecutionException ex) { Throwable cause = ex.getCause(); if (cause instanceof RuntimeException) throw (RuntimeException)cause; if (cause instanceof Error) throw (Error)cause; throw new AssertionError("Unexpected checked exception: " + cause); // it is impossible, because run() method in tasks does not declare any exceptions } catch (InterruptedException ex) { throw new java.io.IOError(ex); }
Before finishing, this method calls
releaseThreadPool(java.util.concurrent.ExecutorService)
method for the used pool (in finally section).As you see, if java.util.concurrent.ExecutionException is thrown while calling one of results[...].get(), this exception is caught, and this method throws the result of its getCause() method. In other words, all possible exceptions while performing tasks are thrown as if they would be performed in the current thread.
If java.lang.InterruptedException is thrown while calling one of results[...].get(), this exception is also caught, and this method throws java.io.IOError. (In Java 1.5, which does not support java.io.IOError, the similar net.algart.arrays.IOErrorJ5 exception is thrown instead: this branch is not listed above.) Usually, you should avoid interrupting the threads, processing AlgART arrays, via Thread.interrupt() technique (which leads to java.lang.InterruptedException): see the package description about runtime exceptions issue.
- Parameters:
threadFactory
- the factory, passed togetThreadPool(java.util.concurrent.ThreadFactory)
method to get the necessary thread pool; may be null, then some default thread factory will be used.tasks
- the tasks which should be performed.- Throws:
NullPointerException
- if tasks argument or one of the tasks is null.- See Also:
-
performTasks
Equivalent toperformTasks(java.util.concurrent.ThreadFactory, Runnable[])
method with the only difference, that the thread pool is got viagetThreadPool(sourceArray, threadFactory)
method.- Parameters:
sourceArray
- the AlgART array, passed togetThreadPool(Array, java.util.concurrent.ThreadFactory)
method to get the necessary thread pool.threadFactory
- the factory, passed togetThreadPool(Array, java.util.concurrent.ThreadFactory)
method to get the necessary thread pool; may be null, then some default thread factory will be used.tasks
- the tasks which should be performed.- Throws:
NullPointerException
- if tasks argument or one of the tasks is null.
-
performTasks
Equivalent toperformTasks
(java.util.Arrays.copyOfRange(tasks, from, to)) call.- Parameters:
tasks
- the tasks which should be performed.from
- the initial index of the performed task, inclusiveto
- the final index of the performed task, exclusive. (This index may lie outside the array.)- Throws:
NullPointerException
- if tasks argument or one of tasks in the specified range is null.IndexOutOfBoundsException
- if from < 0 or from > tasks.length.IllegalArgumentException
- if from > to.
-
performTasks
Equivalent toperformTasks
(threadFactory, java.util.Arrays.copyOfRange(tasks, from, to)) call.- Parameters:
tasks
- the tasks which should be performed.from
- the initial index of the performed task, inclusiveto
- the final index of the performed task, exclusive. (This index may lie outside the array.)- Throws:
NullPointerException
- if tasks argument or or one of tasks in the specified range is null.IndexOutOfBoundsException
- if from < 0 or from > tasks.length.IllegalArgumentException
- if from > to.
-