Singleton Servlet instance - java

Tomcat makes the servlets as a singleton object, After then, sets this singleton object reference to connection threads as a local variable. After then also, each thread play this local variable as syncronized. Is it right?
I confused, Because servlet is a singleton, so only one instance. But specification said that "do not mark service() method as a syncronized, because at that time the servlet container cannot use the instance pool approach.
Pool and singleton, very confusing in details. does the container uses "volatile" keyword to keep the shared local variebles equal in it's pool?

A servlet is a singleton. That means that every request to that servlet calls the service() method of that single, unique object.
Making the service() method synchronized will thus work fine, except no two requests will ever be able to execute the service() method concurrently: that's what synchronized does.
So, instead of having 10 users each executing the method concurrently, you'll now have 1 user executing it, and 9 others waiting for the method to return, then the next one executing the method while the 8 others wait, etc. It will thus make the servlet very slow if you have concurrent requests, and will under-use the resources of your web server.
So, in short, your servlet must be thread-safe: it must allow for concurrent method executions, in a safe way.

Related

Why does the init() method of a servlet run in a different thread?

This is an excerpt from the book "Head First Servlets and JSP". What I don't understand is why the init() method alone runs in thread A, and the service() methods that come after run in a different thread, B.
Does this mean every request from the browser to the servlet gets two threads? Or is init() common for all servlet instances that a container might create? That would be wrong because it is not a static method?
The servlet is initialized just once by init(), but for every new request a new thread is created or allocated from a pool to invoke that servlet instance on the appropriate method.
The HttpRequest and HttpResponse objects will be new for each new request, and the thread, but not the servlet instance.
This description applies to single servlet instance. Intuitively you can think of it as processing requests in other threads not to block the main thread. If the request is time-costly, there is no point in freezing the application to serve it, so every request leads to fork.

What is the use of ThreadLocal?

What is the use of ThreadLocal when a Thread normally works on variable keeping it in its local cache ?
Which means thread1 do not know the value of same var in thread2 even if no ThreadLocal is used .
With multiple threads, although you have to do work to make sure you read the "most recent" value of a variable, you expect there to be effectively one variable per instance (assuming we're talking about instance fields here). You might read an out of date value unless you're careful, but basically you've got one variable.
With ThreadLocal, you're explicitly wanting to have one value per thread that reads the variable. That's typically for the sake of context. For example, a web server with some authentication layer might set a thread-local variable early in request handling so that any code within the execution of that request can access the authentication details, without needing any explicit reference to a context object. So long as all the handling is done on the one thread, and that's the only thing that thread does, you're fine.
A thread doesn't have to keep variables in its local cache -- it's just that it's allowed to, unless you tell it otherwise.
So:
If you want to force a thread to share its state with other threads, you have to use synchronization of some sort (including synchronized blocks, volatile variables, etc).
If you want to prevent a thread from sharing its state with other threads, you have to use ThreadLocal (assuming the object that holds the variable is known to multiple threads -- if it's not, then everything is thread-local anyway!).
It's kind of a global variable for the thread itself, so that any code running in the thread can access it directly. (A "really" global variable can be accessed by any code running in the "process"; we could call it ProcessLocal:)
Is global variable bad? Maybe; it should be avoided if we can. But sometimes we have no choice, we cannot pass the object through method parameters, and ThreadLocal proves to be useful in many designs without causing too much trouble.
Use of ThreadLocal is when an object is not thread-safe, but you want to avoid synchronizing access. So each thread stores data on its own Thread local storage memory. By default, data is shared between threads.

Marking servlet instance variables defined in "init" as "volatile"

Is it necessary to mark all the servlet instance variables as "volatile" (or to access them from within synchronized sections)? Including those defined in the "init" method, and not modified afterwards?
I understand that the "init" method is called by one thread, and the variable will be accessed by another thread, so it seems to be necessary. Or maybe not? Is there any mechanism that guarantees that the current values of instance variables will be visible to all the other threads when the "init" method is finished?
The servlet container will make sure there is a memory barrier between the initialization of the servlets and their invocations. You shouldn't have to do anything.
Note: I haven't found such a requirement in the spec, but I would consider it a failure of the container not to do it. BTW, in GenericServlet, the instance variable ServletConfig config initialized by the init method is not marked as volatile.

Need for thread safety when using a SinglethreadExecutor [duplicate]

This question already has answers here:
Is ExecutorService (specifically ThreadPoolExecutor) thread safe?
(6 answers)
Closed 4 years ago.
I was working on a Java EE app that took in user requests from a UI and then keyed off a lon workflow asynchronously for each of these requests using ExecutorService (SinglethreadExecutor). Now since i was using a SinglethreadExecutor and because there was genuine need for the requests to be served one at a time, i did not feel the need for thread safety.
Is my understanding correct ?
Recently i had asked a question Issue when executing asynchronous tasks using ExecutorService and the solution to this question was that i make my code thread safe.
I'm looking if any shared resources that I'm using in my code is causing the need for this thread safety but would just like to be sure that my understanding of
the scenario is correct.
FYI, I have implemented my ExecutorService in a servlet as mentioned in Running a background Java program in Tomcat
Your requests will be passed to a different thread to be executed. Even if this thread doesn't access shared data structures, the passing of the request to the thread and the returning of the result need to be properly synchronized.
If you use one of the submit or invoke methods which use a Future object for returning the results, you can assume that the appropriate synchronization is performed. The javadoc for ExecutorService says this:
Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task, which in turn happen-before the result is retrieved via Future.get().
In short, if the requests / tasks don't use shared data structures and you use the interface methods provided, then you should be OK.
There are two things that you need to consider when you need to make something "thread safe": When does a thread make data visible to anyone else? When does a thread try to read shared data?
Imagine this situation: Thread A gets the request. It works a bit on it. Then it calls a method foo() that gets the request as a parameter. foo() starts a new thread. The thread puts the reference to the request as a private, non-final field.
In hardware, thread A has copied the request into the L1 cache of the CPU core on which it runs. Since there is no synchronization between the two threads, A has no idea that some other thread might want to read the modified request, so it never flushes the cache (or it does it too late).
This means that thread B will get a stale request object. It won't see any changes made by thread A. As you can imagine, this usually works: If A doesn't change the request, B works. It breaks as soon as you change the code of A and you have a "but it worked yesterday!" situation.
To fix this, you must tell A to flush its caches even if the current version of your code works without it. There are several ways to do it; Stephen C described one. Two other ways:
You can synchronize foo() - A thread must flush when it enters a synchronized block.
Make the request a final field of B - Object graphs referenced via final fields must be completely flushed at the time the type construction has completed (where type == the class which contains the final field).

Question regarding multi-threaded environment of servlet

If there is a servlet, inside a servlet container such as Websphere. The servlet are executed by some threads. I would like to ask, what does the threads share? How variables are shared between them?
Do they have a local copy of the following variables?
1) private/protected/public final Semaphore permits = new Semaphore(50);
2) private/protected/public final static Semaphore permits = new Semaphore(50);
3) private/protected/public Semaphore permits = new Semaphore(50);
4) private/protected/public static Semaphore permits = new Semaphore(50);
How should I declare the semaphore so that I can use semaphore to control them? I don't want them to have each of them a copy of the semaphore. Thanks.
Threads are run by Websphere thread pool and you should not be concerned about accessing them or sharing information via them.
Your semaphore will be shared if you declare it static in your servlet, for as long as all classes that use it live in the same application under the same classloader. However, there is a big risk in this case that if your execution path does not release permit (for example due to exception) you may end up with all threads blocked.
Each thread has its own stack, but all share the same memory space. With that in mind, a single instance can be shared, and so its state/properties, among multiple threads. Hence, we need to take care of state using synchronisation or similar techniques.
If you define a static variable or a single instance of servlet will be used -- which is highly likely but no guarantee, then it would be the same for all threads.
Nonetheless, you should create a class which provide a singleton semaphore to be used in servlet. That way servlet instances will be using the one and the same semaphore object, no matter what.
If you want to share a semaphore, it must be created by one thread, then handed out to the others (via some form of (possibly static) getter method) when they need it.
If you create the Semaphore object in each object, they'll all have different ones, defeating the purpose.
Servlets must be thread safe. This means your servlets should be "stateless" (unless you really know what you're doing). Essentially, use only local variables - not fields.
If you want to share state, by all means use fields of your servlet, or use classes with static fields and static getters (like the singleton pattern)
Servlets should be threadsafe. Meaning if they have any state, they should be synchronized. Try avoiding saving some state inside servlets. They should contain only business/controller logic. Any state you want to save, put them in servletcontext/request/session which are synchronized by the container.
Each servlet is executed in a new thread.. Technically, there is worker threads that waits for requests, when a http request comes to servlet container, this one instantiates a new servlet (depending to servlets defined in web.xml) and passes it to the worker thread. So logically each variable is not seen by other servlet instances. Now if you want to make your variable visible by all servlet instances you have to define it as static so it will be shared between all instances of the same class.
You should not count on two instances of a servlet even being in the same JVM. Containers can be replicated and your Servlets need to be stateless. Besides the Java EE spec does not allow you to do any threading manipulation within. The containers may allow it, but the behaviour then becomes implementation specific. By putting semaphores in there you are interfering with the pooling and can cause issues. Use Sessions if you need to differentiate between different users.

Categories

Resources