web app, jsp, and multithreaded - multithreading

I'm currently building a new web app, in Java EE with Apache Tomcat as a webserver.
I'm using jsps and servlets in my work.
my question is:
I have a very standard business logic. None of it is synchronized, will only a single thread of my web app logic will run at any given time?
Since making all functions "synchronized" will cause a huge overhead, is there any alternative for it?
If i have a static method in my project. that makes a very simple thing, such as:
for (int i=0;i<10000;i++ ) {
counter++;
}
If the method is not thread safe, what is the behavior of such method in a multi user app? Is it unexpected behavior?!
and again in a simple manner:
if i mean to build a multi user web app, should i "synchronize" everything in my project? if not all , than what should i sync?

will only a single thread of my web app logic will run at any given time?
No, the servlet container will create only one instance of each servlet and call that servlet's doService() method from multiple threads. In Tomcat by default you can expect up to 200 threads calling your servlet at the same time.
If the servlet was single-thread, your application would be slow like hell, see SingleThreadModel - deprecated for a reason.
making all function "synchronized" will make a huge overhead, is there any alternative for it?
There is - your code should be thread safe or better - stateless. Note that if your servlet does not have any state (like mutable fields - unusual), it can be safely accessed by multiple threads. The same applies to virtually all objects.
In your sample code with a for loop - this code is thread safe if counter is a local variable. It is unsafe if it is a field. Each thread has a local copy of the local variables while all threads accessing the same object access the same fields concurrently (and need synchronization).
what should i sync?
Mutable, global, shared state. E.g. In your sample code if counter is a field and is modified from multiple threads, incrementing it must be synchronized (consider AtomicInteger).

Related

Is ASP.NET Core Session implementation thread safe?

I know that there is an analogous question but that is about ASP.NET and not about ASP.NET Core. The answers are 7-9 years old, and mixing there talking about ASP.NET and ASP.NET Core may not be a good idea.
What I mean thread safe in this case:
Is it safe to use the read write methods (like Set(...)) of the Session (accessed via HttpContext, which accessed via an injected IHttpContextAccessor) in multiple requests belonging to the same session?
The obvious answer would be yes, because if it would not be safe, then all developers should make their session accessing code thread safe...
I took a look of the DistributedSession source code which seems to be the default (my session in the debugger which accessed as described above is an instance of DistributedSession) and no traces of any serialization or other techniques, like locks... even the private _store member is a pure Dictionary...
How could be this thread safe for concurrent modification usage? What am I missing?
DistributedSession is created by DistributedSessionStore which is registered as a transient dependency. That means that the DistributedSessionStore itself is implicitly safe because it isn’t actually shared between requests.
The session uses a dictionary as the underlying data source which is also local to the DistributedSession object. When the session is initialized, the session initializes the _store dictionary lazily when the session is being accessed, by deserializing the stored data from the cache. That looks like this:
var data = _cache.Get(_sessionKey);
if (data != null)
{
Deserialize(new MemoryStream(data));
}
So the access to _cache here is a single operation. The same applies when writing to the cache.
As for IDistributedCache implementations, you can usually expect them to be thread-safe to allow parallel access. The MemoryCache for example uses a concurrent collection as the backing store.
What all this means for concurrent requests is basically that you should not expect one request to directly impact the session of the other request. Sessions are usually only deserialized once so updates that happen during the request (by other requests) will not appear.

How to run a time consuming task on startup in a web application while deploying it

we are facing an issue with initializing our cache at server startup or application deployment. Initializing the cache involves
Querying a database to get the list of items
Making an rmi call for each item
Listening to the data on a JMS queue/topic
Constructing the cache
This initialization process is in startup code. All this is taking lot of time due to which the deployment is taking lot of time or server start time is increasing.
So what I proposed is to create a thread in the startup and run the initialization code in it. I wrote a sample application to demonstrate it.
It involves a ServletContextListener, a filter. In the listener I am creating a new thread in which the HeavyProcess will run. When it finishes an event will be fired which the filter will be listening. On receiving the event the filter will allow incoming http requests. Until then the filter redirects all clients to a default page which shows a message that the application is initializing.
I presented this approach and few concerns were raised.
We should not ideally create a thread because handling the thread will be difficult.
My question is why cant we create a thread like these in web applications.
If this is not good, then what is the best approach?
If you can use managed threads, avoid unmanaged ones. The container has no control over unmanaged threads, and unmanaged threads survive redeployments, if you do not terminate these properly. So you have to register unmanaged threads, and terminate these somehow (which is not easy as well, because you have to handle race-conditions carefully).
So one solution is to use #Startup, and something like this:
#Schedule(second = "*/45", minute = "*", hour = "*")
protected void asyncInit(final Timer timer) {
timer.cancel();
// Do init here
// Set flag that init has been completed
}
I have learned about this method here: Executing task after deployment of Java EE application
So this gives you an async managed thread, and deployment will not be delayed by #PostConstruct. Note the timer.cancel().
Looking at your actual problem: I suggest using a cache which supports "warm starts".
For example, Infinispan supports cache stores so that the cache content survives restarts. If you have a cluster, there are distributed or replicated caching modes as well.
JBoss 7 embeds Infinispan (it's an integrated service in the same JVM), but it can be operated independently as well.
Another candidate is Redis (and any other key/value store with persistence will do as well).
In general, creating unmanaged threads in a Java EE environment is a bad idea. You will loose container managed transactions, user context and many more Java EE concepts within your unmanaged thread. Additionally unmanaged threads may block the conainer on shutdown if your thread handling isn't appropriate.
Which Java EE Version are you using? Perhaps you can use Servlet 3.0's async feature?
Or call a asynchronous EJB for doing the heavy stuff at startup (#PostConstruct). The call will then set a flag when its job is done.

ColdFusion singleton object pool

In our ColdFusion application we have stateless model objects.
All the data I want I can get with one method call (it calls other internally without saving the state).
Methods usually ask the database for the data. All methods are read only, so I don't have to worry about thread safety (please correct me if I'm wrong).
So there is no need to instantiate objects at all. I could call them statically, but ColdFusion doesn't have static methods - calling the method would mean instantiating the object first.
To improve performance I have created singletons for every Model object.
So far it works great - each object is created once and then accessed as needed.
Now my worry is that all requests for data would go through only 1 model object.
Should I? I mean if on my object I have a method getOfferData() and it's time-consuming.
What if a couple of clients want to access it?
Will second one wait for the first request to finish or is it executed in a separate thread?
It's the same object after all.
Should I implement some kind of object pool for this?
The singleton pattern you are using won't cause the problem you are describing. If getOfferData() is still running when another call to that function gets called on a different request then this will not cause it to queue unless you do one of the following:-
Use cflock to grant an exclusive lock
Get queueing connecting to your database because of locking / transactions
You have too many things running and you use all the available concurrent threads available to ColdFusion
So the way you are going about it is fine.
Hope that helps.

Spring + Hibernate session management across multiple threads

I am building a system, where each request from a client side spawns multiple threads on server side. Each thread then is using one or more DAOs (some DAOs can be used by more than one thread at the time). All DAOs are injected (#Autowired) to my thread classes by Spring. Each DAO receives SessionFactory injected as well.
What would be proper way of managing Hibernate sessions across these multiple DAOs so I would not run into problems because of multithreaded environment (e.g. few DAOs from different threads are trying to use the same session at the same time)?
Would be enough that I specify hibernate.current_session_context_class=thread in Hibernate configuration and then everytime in DAO simply use SessionFactory.getCurrentSession() to do the work? Would it properly detect and create sessions per thread as needed?
Yes. It is enough.
When setting hibernate.current_session_context_class to thread , the session returned from SessionFactory.getCurrentSession() is from the ThreadLocal instance.
Every thread will have their own, independently ThreadLocal instance, so different threads will not access to the same hibernate session.
The behaviour of SessionFactory.getCurrentSession() is that: if it is called for the first time in the current thread, a new Session is opened and returned. If it is called again in the same thread, the same session will be returned.
As a result , you can get the same session to use in different DAO methods in the same transaction code by simply calling SessionFactory.getCurrentSession(). It prevents you from passing the Hibernate session through the DAO method 's input parameters in the case that you have to call many different DAO methods in the same transaction code.

Prevent thread blocking in Tomcat

I have a Java servlet that acts as a facade to other webservices deployed on the same Tomcat instance. My wrapper servlet creates N more threads, each which invokes a webservice, collates the response and sends it back to the client. The webservices are deployed all on the same Tomcat instance as different applications.
I am seeing thread blocking on this facade wrapper service after a few hours of deployment which brings down the Tomcat instance. All blocked threads are endpoints to this facade webservice (like http://domain/appContext/facadeService)
Is there a way to control such thread-blocking, due to starvation of available threads that actually do the processing? What are the best practices to prevent such deadlocks?
The common solution to this problem is to use the Executor framework. You need to express your web service call as Callable and pass it to the executor either as it stands, or as a Collection<Callable> (see the Javadoc for complete list of options).
You have two choices to control the time. First is to use parameters of an appropriate method of the Executor class where you specify the max web service timeout. Another option is to do get the result (which is expressed as Future<T>) and use .get(long, TimeUnit) to specify the maximum amount of time you can wait for a result.

Resources