I am too much confused the difference between #EnableAsync and AbstractDispatcherServletInitializer#isAsyncSupported().
As per this link,
The isAsyncSupported protected method of AbstractDispatcherServletInitializer provides a single place to enable async support on the DispatcherServlet and all filters mapped to it. By default this flag is set to true
Based on my knowledge #EnableAsync is to enable scan #Async annotations and provide multi-threading support. But still I am unable to understand when to use AbstractDispatcherServletInitializer#isAsyncSupported()
There is a big difference between the two, #EnableAsync with #Async are not concerned with spring-web-mvc, they allow the execution of a method asynchronously using a TaskExecutor. For example, if you had a clean up service that deletes all logs in a server, you can allow its doCleanUp method to run asynchronously without having to write the scheduling code, spring will take care of it for you:
public class CleanUpService {
#Async
public void doCleanUp() {
// This code will be executed using a different thread than the calling thread by a TaskExecuter
}
}
As you can see this is not related to web development in particular. Also note that this method returns void, but if you wanted it to return a result, for instance CleanupStatistics, you can't just write the method like this
#Async
public CleanupStatistics doCleanUp() {
// This code will be executed using a different thread than the calling thread by a TaskExecuter
return new CleanupStatistics("someinformation");
}
You are required to return either void or a Future. A Future represents the result of an asynchronous computation that you can use to obtain the result of the computation when it becomes available. We will get back to Future and see how it can be used in controller methods while isAsyncSupported is true.
isAsyncSupported is a totally different story, this flag enables Servlet 3.0 asynchronous request processing, prior to Servlet 3.0 a servlet container (Tomcat for instance) would have a thread pool that handles the processing of Http requests, each thread would handle the request till the processing is complete, even if the thread had to stay idle, for example, to wait for a database query to finish or for an API call result to come back. This affects the scalability of the servlet container. In Servlet 3.0 requests can be handled asynchronously, the container thread will call your handler method, in its turn the handler method can schedule its work to be done asynchronously and return immediately, freeing the container thread to process other requests, after the result is available any container thread can resume the processing of the request. From the prospective of the client, nothing has changed, the client, all that time, is still waiting for the result to come back, but from the perspective of the server, the container threads are better utilised.
In spring-mvc you can trigger asynchronous request processing for a controller method by returning certain java types, for example
DeferredResult
Callable
ListenableFuture
CompletionStage
CompletableFuture
Reactive types
and streaming types
If you wanted to use #Async with isAsyncSupported you could write a controller method that calls a method annotated with #Async and returns ListenableFuture.
You can learn more about task execution and scheduling here. And more about Servlet 3.0 asynch here.
If we want to experience benefits provided by Spring MVC and don't want to manually register DispatcherServlet it'll be better to use: AbstractDispatcherServletInitializer. It adds two abstract methods: createServletApplicationContext() and getServletMappings().
First method returns WebApplicationContext that will be passed to DispatcherServlet, which will be automatically added into container ServletContext. This context will be established as a child of the context returned by createRootApplicationContext() method. Second method -returns mappings that are used during servlet registration.
The #EnableAsync annotation switches on Spring’s ability to run #Async methods in a background thread pool. For Enabling asynchronous processing with Java configuration got by simply adding the #EnableAsync to a configuration class.
#EnableAsync
#Configuration
public class SpringAsyncConfigurer implements AsyncConfigurer {...}
#Async is applicable only to the public methods.
Calling the #Async method within the same class woould not work.
Related
I have a Java EE app that's deployed on WildFly AS.
I have a method annotated with #Asynchronous and I need to set the max number of threads for this method.
I configured a new <managed-executor-service> in server config, but I don't know how to bind it to an async method.
This link: https://developer.jboss.org/message/851027#851027
provides a good answer to how (or when) to use #Asynchronous and when to use JSR-236 ExecutorService and concurrency utilities:
In short, #Asynchronous is a annotation (EE6) to mark an EJB method as async.
You can invoke the method and keep the future object to check whether the method is finished and get the result. The EJB Concurrency Utilities are provided to have a safe way in EE7 to delegate work to a parallel thread. Threads started by this ConcurrentUtilities are managed by the container.
In difference to a direct start of a Thread (which is not allowed for an EE application). There is less overhead than using #Async and you have a bit more control.
See also this link about how to inject a MES:
http://www.adam-bien.com/roller/abien/entry/injecting_an_executorservice_with_java
I have a singleton EJB(3.1) which is using default container managed concurrency and default (LockType.Write) for all methods, since its not specified explicitly.
I have an Asynchronous method which looks as below:
#Asynchronous
#TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
#AccessTimeout(-1)
public AsyncResult<Boolean> myAsyncMethod(....){
}
My question is, when invoked, will this method lock the whole singleton bean till the above method completes processing or will it lock only till the time the method returns the Future object to the client ?
Also what effect will "#AccessTimeout(-1)" the on the concurrency of this method/bean.
My question is, when invoked, will this method lock the whole
singleton bean till the above method completes processing or will it
lock only till the time the method returns the Future object to the
client ?
The singleton bean is never locked at all on the client thread. The client thread schedules the asynchronous method and returns a Future without accessing the bean. The thread that eventually executes the asynchronous method will lock the bean for the duration of the method execution.
Also what effect will "#AccessTimeout(-1)" the on the concurrency of
this method/bean.
The #AccessTimeout(-1) will cause the thread that eventually attempts to execute the asynchronous method to block until the container-managed lock can be acquired.
Answer to Q1: since the method is marked #Asynchronous, it will return immediately. No blocking what so ever
Answer to Q2: Using #AccessTimeout(-1) on a session bean method/class means that once a thread enters that method, it will block for ever until it completes processing. However, in this case its not a concern since the #Asynchronous will kick in, free up the calling thread and start the processing in a different background thread
Coincidentally, I happened to write a blog post on this topic couple of days back. I would also recommend reading up on the EJB 3.2 specification document - its a reliable and thorough reference material
In Servlet 3.0, an application's ServletContainerInitializer implementation (if any) is called when the application first BEGINS starting and any ServletContextListeners (if any) are called soon after, but still as the context is BEGINNING initialization. Likewise, if you have any Servlets with load-on-startup set, their init methods are called as the Servlets are starting up, but still BEFORE the context completes initialization.
In all of these cases, the context has not completed initialization. That is fine and I understand and agree with the reasons for that. What I'm looking for, however, is a way to be notified immediately AFTER the context has completed initialization and is open for business. As an example, it should be possible (not saying I want to do this) for this listener of sorts to perform a web request to the application it resides in. That wouldn't be possible for any of the above mentioned listeners/initializers, since they are called before the application is listening for requests.
Is it possible to do this? Doesn't have to strictly be a Servlet-spec-provided method. Could be Spring Framework or some other library that performs this task.
You can use JBoss Seam they have servlet lifecycle event #Initialized.
public void observeServletContextInitialized(#Observes #Initialized ServletContext ctx)
{
System.out.println(ctx.getServletContextName() + " initialized");
}
I am new to server side coding and JSP/servlets. I have a code which has 3 classes. 1st is a Serv class inherited from java httpservlet. In this i have doPost() method implemented. In doPost() i use object of the 2nd class ResourceClass. ResourceClass is a singleton class. Hence essentially to use any method is do something like ResourceClass.getInstance().readResource();
Now readResource furthur uses Java Native access library to read a resource from disk. Now my question is Since as i understand if 1000 clients connect to my server(Apache Tomcat) for each new request i will have a new servlet serving the request. But all these servlets will essentially use the same singleton object. Hence will this reading be thread safe.
I do not change any internal state. So i think it wont effect my output hence the whole stuff is Idempotent. But will all these requests be queued making the singleton class object a bottleneck. Or will each servlet has its own copy.
Also if i change the Resource state then in that case will it be thread safe.
First of all, you won't have a new servlet for each request. The same, unique instance of servlet will be used to concurrently handle all the requests. The servlet is also a singleton: the web container instantiates only one instance.
You say that the requests to your ResourceClass singleton will be queued. They won't, unless you mark the method as synchronized or use some other locking mechanism. If you don't, then the threads will invoke your singleton method concurrently.
Whether it's thread-safe or not is impossible to say without seeing the code of your singleton and the code of the JNI library. The fact that it's read-only is a sign that it could be thread-safe, but it's not guaranteed.
In a Java EE server, you only have 1 instance of each servlet.
On the other hand, each http request is processed by the server in its own thread.
There is one instance of ResourceClass because it's a singleton so you will have a bottleneck if the readResource() method is synchronized.
The Working with the BeginMethod/EndMethod Pattern section of Using an Asynchronous Controller in ASP.NET MVC refers to a Sync() method. It is not linked and I am having trouble finding documentation on it through google searches since sync is too common a term. Can someone point me in the write direction?
To make sure that you have access to
the HttpContext.Current instance and
to avoid the race condition, you can
restore HttpContext.Current by calling
Sync() from the callback method.
When you spawn asynchronous operations by calling BeginXyz / EndXyz methods from within your controller action, the threads handling the asynchronous response are not under the control of ASP.NET. As such, you can't touch HttpContext, the controller instance, or any other shared state from within those threads. Calling the Sync() method basically synchronizes access to the request; it restores HttpContext.Current and grants you access to touch HttpContext, the controller, etc., but only for the duration of the Sync() call. The RegisterTask() extension method from MVC Futures attempts to make this a bit easier, as you basically pass it delegates to the target Begin and End methods, and the RegisterTask() helper will ensure that the End thread executes within an appropriate synchronization context.
If you're spawning asynchronous operations by calling XyzAsync / XyzCompleted methods from within your controller action, you don't have to worry about this, as the completed handler automatically runs within a synchronization context.
It's a method of the AsyncManager class. http://msdn.microsoft.com/en-us/library/system.web.mvc.async.asyncmanager.sync.aspx