The Springframework has @Async annotation.
it simplifies the asynchronous method execution and hides the implementation details. In order to have a dependable asynchronous execution mechanism, few more factors need our attention.
First,
the sample of the usage of the Async annotation:
@Async
void doSomething() {
// activities will be executed asynchronously
}
@Async("anExecutor")
Future<String>
doThenReturnSomething(String id) {
// will be executed asynchronously
}
Other possible return
types:
JDK 8’s java.util.concurrent.CompletableFuture
boolean
cancel(boolean mayInterruptIfRunning)
boolean
complete(T value)
Spring’s org.springframework.util.concurrent.ListenableFuture
void addCallback(ListenableFutureCallback<?
super T> callback)
void addCallback(SuccessCallback<? super
T> successCallback, FailureCallback failureCallback)
JBoss’s org.jboss.threads.AsyncFuture
Void
asyncCancel(boolean interruptionDesired)
AsyncFuture.Status getStatus()
ThreadPoolTaskExecutor This implementation is the most commonly used one.
<task:executor
id="executorWithCallerRunsPolicy"
pool-size="5-25"
queue-capacity="100"
keep-alive="120"
rejection-policy="CALLER_RUNS"/>
From Springframework document:
By default, the queue is unbounded, but this is
rarely the desired configuration, because it can lead to
OutOfMemoryErrors
if enough tasks are added to that queue
while all pool threads are busy.
TaskRejectedException,
AbortPolicy,
DiscardPolicy
or DiscardOldestPolicy,
CallerRunsPolicy
First, let’s consider the case, as mentioned above, when a task
is rejected. By default, when a task is rejected, a thread pool executor will
throw a
TaskRejectedException
.
However, the rejection policy is actually configurable. The exception is thrown
when using the default rejection policy which is the AbortPolicy
implementation. For applications where
some tasks can be skipped under heavy load, either the DiscardPolicy
or DiscardOldestPolicy
may be configured instead. Another
option that works well for applications that need to throttle the submitted
tasks under heavy load is the CallerRunsPolicy
. Instead
of throwing an exception or discarding tasks, that policy will simply force the
thread that is calling the submit method to run the task itself. The idea is
that such a caller will be busy while running that task and not able to submit
other tasks immediately. Therefore it provides a simple way to throttle the
incoming load while maintaining the limits of the thread pool and queue.
Typically this allows the executor to "catch up" on the tasks it is
handling and thereby frees up some capacity on the queue, in the pool, or both.
Any of these options can be chosen from an enumeration of values available for
the 'rejection-policy' attribute on the 'executor' element.
The
keep-alive
setting determines the time limit (in
seconds) for which threads may remain idle before being terminated. If there
are more than the core number of threads currently in the pool, after waiting
this amount of time without processing a task, excess threads will get
terminated.
Finally,
When actions are enclosed in tasks
(such as FutureTask) either explicitly or via methods such as submit, these
task objects catch and maintain computational exceptions, and so they do not
cause abrupt termination, and the internal exceptions are not passed to this
method. Please make
sure that the calling method handles the exception properly.
Inside the asynchronous task, most
likely, a remote service call or database access will be invoked. Please
configure proper timeout so that thread will not be blocked or thread will not
hang.
No comments:
Post a Comment