Async-Helper is a Java utility (also an OSGi bundle) to invoke/schedule tasks or fetch data asynchronously using tags/flags in a functional way. This internally utilizes ForkJoin pool to submit the tasks.
This contains various helper classes such as AsyncContext, AsyncTask, AsyncSupplier, SchedulingTask and SchedulingSupplier to perform various asynchronous operations.
Please refer to the JavaDocs also.
- Submitting one or more Runnable(s) to run asynchronously.
- Submitting one or more Supplier(s) to fetch some data asynchronously, which can be then obtained by a tags(key made of one or more Objects)
- Wait for some flag in one thread until that flag is notified in another thread.
- Schedule Runnable(s) and Supplier(s) one time or rotating until a flag.
- Some of the above operations also support option to submit/schedule asynchronously and then wait untill all asynchronous tasks are compete.
Please look into the Unit tests for all the use-cases and examples.
Also refer to the Wiki page for some example usages.
-
Async-Helper is an OSGi bundle now :), to use it directly in OSGi applications.
-
Renamed Async helper class to AsyncContext so that there is option to limit the context of Asynchronous operations. The global context can be obtained using
AscynContext.getDefault()
. -
All the existing helper classes and their methods are now converted from static to instances, so that,
Either their default instances can be obtained using their getDefault() methods,
- AsyncContext ==>
AsyncContext.getDefault()
- AsyncTask ==>
AsyncTask.getDefault()
- AsyncSupplier ==>
AsyncSupplier.getDefault()
- SchedulingTask ==>
SchedulingTask.getDefault()
- SchedulingSupplier ==>
SchedulingSupplier.getDefault()
Or they can be instantiated with a specific arguments.
- AsyncContext ==>
AsyncContext.newInstance()
- AsyncTask ==>
AsyncTask.of(ExecutorService)
orAsyncTask.of(ExecutorService, AsyncContext)
- AsyncSupplier ==>
AsyncSupplier.of(ExecutorService)
orAsyncSupplier.of(ExecutorService, AsyncContext)
- SchedulingTask ==>
SchedulingTask.of(ScheduledExecutorService)
orSchedulingTask.of(ScheduledExecutorService, AsyncContext)
- SchedulingSupplier ==>
SchedulingSupplier.of(ScheduledExecutorService)
orSchedulingSupplier.of(ScheduledExecutorService, AsyncContext)
- AsyncContext ==>
-
The default instances of
AsyncTask
andAsyncSupplier
use a commonForkJoinPool
. But it is possible to get customized instances of these can be obtained by passing a newExecutorService
instance. -
The default instances of
SchedulingTask
andSchedulingSupplier
use a commonScheduledExecutorService
. But it is possible to get customized instances of these can be obtained by passing a newScheduledExecutorService
instance. -
AsyncTask includes a new static helper method
AsyncTask.submitTaskInNewThread(Runnable)
to submit a task by spawning a new thread.
<dependency>
<groupId>org.vishag</groupId>
<artifactId>async-helper</artifactId>
<version>4.0.0</version>
</dependency>
If it is desired to run a set of method calls or code blocks asynchronously, the Async-Helper library includes an useful helper method AsyncTask.submitTasks as in below snippet.
AsyncTask.getDefault().submitTasks(
() -> getMethodParam1(arg1, arg2),
() -> getMethodParam2(arg2, arg3)
() -> getMethodParam3(arg3, arg4),
() -> {
//Some other code to run asynchronously
}
);
If it is desired to wait till all asynchronous codes are completed running, the AsyncTask.submitTasksAndWait varient can be used.
Also if it is desired to obtain a return value from each of the asynchronous method call or code block, the AsyncSupplier.submitSuppliers can be used so that the result can be then obtained by from the result suppliers array returned by the method. Below is the sample snippet:
Supplier<Object>[] resultSuppliers =
AsyncSupplier.getDefault().submitSuppliers(
() -> getMethodParam1(arg1, arg2),
() -> getMethodParam2(arg3, arg4),
() -> getMethodParam3(arg5, arg6)
);
Object a = resultSuppliers[0].get();
Object b = resultSuppliers[1].get();
Object c = resultSuppliers[2].get();
These result can be then passed to the myBigMethod as below.
myBigMethod(a,b,c);
If the return type of each method differ, use the below kind of snippet.
Supplier<String> aResultSupplier = AsyncSupplier.getDefault().submitSupplier(() -> getMethodParam1(arg1, arg2));
Supplier<Integer> bResultSupplier = AsyncSupplier.getDefault().submitSupplier(() -> getMethodParam2(arg3, arg4));
Supplier<Object> cResultSupplier = AsyncSupplier.getDefault().submitSupplier(() -> getMethodParam3(arg5, arg6));
myBigMethod(aResultSupplier.get(), bResultSupplier.get(), cResultSupplier.get());
The result of the asynchronous method calls/code blocks can also be obtained at a different point of code in the same thread or a different thread as in the below snippet.
AsyncSupplier.getDefault().submitSupplierForSingleAccess(() -> getMethodParam1(arg1, arg2), "a");
AsyncSupplier.getDefault().submitSupplierForSingleAccess(() -> getMethodParam2(arg3, arg4), "b");
AsyncSupplier.getDefault().submitSupplierForSingleAccess(() -> getMethodParam3(arg5, arg6), "c");
//Following can be in the same thread or a different thread
Optional<String> aResult = AsyncSupplier.getDefault().waitAndGetFromSupplier(String.class, "a");
Optional<Integer> bResult = AsyncSupplier.getDefault().waitAndGetFromSupplier(Integer.class, "b");
Optional<Object> cResult = AsyncSupplier.getDefault().waitAndGetFromSupplier(Object.class, "c");
myBigMethod(aResult.get(),bResult.get(),cResult.get());