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.
Related
When should one prefer ThreadLocal over synchronization, apart from for the performance improvement? Please explain using a real life example.
ThreadLocal is not an alternative to synchronized. The main problem solved by ThreadLocal is how to manage per-thread static data in an application.
static is something that you should try to avoid whenever you can: It's a recipe for un-testable, brittle code.
When you use ThreadLocal variables these are seen and manipulated by the thread using it ONLY, no other thread can see them. Thread local variables dies when the thread does too.
And one should be careful then using ThreadLocal variables when using thread pools.
ThreadLocal variables are put in a special memory space called Thread private stack.
Shared variable are put in the heap memory space where they are shared among all threads and they are either synchronized or not.
So it is more about use case than performance.
One can use ThreadLocal variable to hold a connection to some DB where the connection is associated with the current thread ONLY and no need for other thread to see it and a need to synchronize it. The cache - a shared in memory map or list,for example, however, is shared among all threads in a server application and it must be synchronized.
The only reason to use Threads is for performance reasons (or perhaps you like confusion ;).
AFAICS If you discount performance, there is not reason to use Threads, ThreadLocal nor synchronzied.
ThreadLocal provides global variable access with in a Thread. This will help when you want to share a variable across methods and still retain Thread scope.
J2EE application servers use ThreadLocal for tracking Transaction, Security context with out passing around
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.
I'm very new to J2EE, so apologies if this is obvious. I have to work around a bad database design, which has an update which cannot be done safely in parallel. The easiest way to fix this (for now) is to place a mutex protection around the method call to serialize it's access.
I understand that you can't safely just use the synchronised keyword on the method in J2EE as the container may interfere. Is there a "supported" way in J2EE to make a mutex/semaphore/lock in an EJB to ensure access to a method is serialised for the entire J2EE application?
Try using a static object as the mutex, for example:
private static final Object mutex = new Object ();
public void someMethod() {
synchronized(mutex) {
// do work that must be globally synchronous
}
}
The reason that using synchronized on the method itself won't work for you is that the Java EE container may create multiple instances of EJBs but the methods marked synchronized are only protected on a per-instance basis (where each instance can have only one thread executing a synchronized method at a time, but multiple instances can be accessed concurrently).
Just for prosperity, the java.util.concurrent are all approved for use within the container. Blocking using a Semaphore will work within a single container, but you will need a higher level of synchronisation to maintain synchronisation in a cluster.
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.
Servlets are not thread safe. So if I use a static function of a class, What will happen when multiple requests come at the same time. How will they deal with the static function?
You'll have to synchronize it if accesses shared, mutable data. If the data is immutable or read-only or on the stack you should be fine.
It depends on what kind of static method do you have whether it is stateless or not. If it is stateless, and not referencing anything outside from your method's scope it will be thread safe.
if you are using static method in servlets you need to make them thread safe by
Using only local variables when state of the variable may change
or use static variable if they dont change or use synchronize access method
and you can amke function thread safe by implementing the SingleThreadModle interface or by 'synchronize' construct.