The main question is about static fields and singleton instances (for configs, etc.) - are instances of one process running in different threads, as usual servlet requests?
If look deeper - do different #ProcessApplication run in one JVM and will see the same singletons? I don't think so. I know exactly that their classes don't see each other and can have equal names (because of different classLoaders?)
Haven't found any meaningful info on these important themes about Camunda, will appreciate your answers.
I had this same question for one of our scenario while back, and read their Javadoc as mentioned here for a servlet container. Extracting Javadoc,
Invocation Semantics
When the {#link #execute(java.util.concurrent.Callable)} method is
invoked, the servlet process application modifies the context
classloader of the current Thread to the classloader that loaded the
application-provided subclass of this class. This allows,
the process engine to resolve {#link JavaDelegate} implementations using the classloader of the process application
This pretty much explain everything you want to know, since the behavior is very similar to how a web container operates. If you want to know how other container implementations behaves, you can check the respective Javadocs of classes in this package.
To answer your question:
Yes. Thread-safety is required for the shared-resources accessed by JavaDelegate in the same process application. According to the documentation (see below) they create a new instance of delegate each time a task is going to be executed.
Note!
Each time a delegation class referencing activity is executed, a
separate instance of this class will be created. This means that each
time an activity is executed there will be used another instance of
the class to call execute(DelegateExecution).
Therefore, at any time there can be many delegate instances actively running due to the multiple invocation of Process Definitions. So, if they are accessing a shared resource, then they need to be synchronized (thread-safe), because, that shared resources (static or singleton) is local to the process application and loaded by respective application classloader according to above Invocation Semantics Javadoc.
Hope this helps.
Related
How unique is the thread context's classloader. Is it reset everytime a thread is started?
Can we always be sure that 2 parallel threads will never have the same context classloader?
I see some frameworks like Axis relying on this to get and set run-time setting variables.
How unique is the thread context's classloader.
Not even remotely.
Is it reset everytime a thread is started?
When a thread is created, it doesn’t have context loader that can be reset. It will inherit the parent thread’s context loader. Starting the thread doesn’t change its context loader.
Can we always be sure that 2 parallel threads will never have the same context classloader?
That would be actually very unlikely. As said, threads inherit the parent’s loader by default, so unless someone calls setContextClassLoader explicitly with a different loader, the default application class loader, as returned by ClassLoader.getSystemClassLoader() will be the used by all threads. Even in environments with different class loaders, it’s unlikely to have as much class loaders as threads.
I see some frameworks like Axis relying on this to get and set run-time setting variables.
It’s the main use of the feature, frameworks using the current thread’s context class loader by convention, but of course, for loading classes and resources, not to assume uniqueness of these loaders. The JVM never uses this context class loader on its own, as symbolic references found in a class are resolved through the defining class loader of that class. The same applies for Class.forName(String) (without a class loader argument). It requires code actively invoking getContextClassLoader() and using the returned loader for class loading, to make this feature relevant.
Don’t confuse class loaders with ThreadLocal variables.
Probably the stupidest question you have ever heard.
Inside the Web container how more than 1 object of the same class is getting created/managed which has same reference variable... Let me explain with an example.
Inside my controller class I have a code piece
AdminUser adminUser= new AdminUser();
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
How is it possible, is it 2 different threads?
Who is managing this threads, web container?
If so, how web container is doing it, is it wrapping application
code with threadLocal?
If its different threads, to maintain a global object (say a counter
for the admins visit counts), "static" won't suffice... it needs to be
"volatile" instead, correct?
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
No.
If that line of code is in a method, the variable is on the stack, and there can be as many instances as there are concurrent invocations of the method, including recursions and calls by multiple threads.
If it's non-static member initialization code, the variable is in the object, and there are as many instances as there are objects.
If the object is a bean, the number of them depends on the object's scope: if application, one; if session, one per session; if view, one per view; etc.
If it's static member initialization code, it shouldn't be.
How is it possible, is it 2 different threads?
See above.
Who is managing this threads, web container?
Yes, and it is also managing bean instances.
If so, how web container is doing it, is it wrapping application code with threadLocal?
No. See above.
If its different threads, to maintain a global object (say a counter for the admins visit counts), "static" won't suffice... it needs to be "volatile" instead, correct?
No. You can maintain it as an instance member of an application-scoped bean.
You should avoid statics completely in a web-app, apart from constants and caches, which you should also avoid.
Are several factors that influence to answer your questions, the j2ee has own specification that manufacturers must follow, and others, they should simply implement as they wish. Is to give the performance they want, or how they should act in certain moments. A Jboss is certainly different from Apache Tomcat performance issues, which makes it hard to answer your first question. Then answer: "It depends on which vendor you are talking. Specifically what Container?"
It also depends if you implement Enterprise JavaBeans in your code because then probably several Beans (objects) will be started (depending on the container) and each request from a client he might share these Beans or create new ones to account for the competition.
Answering their fourth question, the best method would be a counter through a Singleton Session Bean (EJB implementation), in my opinion. But you could do through a static class, in which all other objects can share, but would have to resolve the competition between objects. EJB resolves this competition for you without you having to waste time with it. is for this and many other things the solution of the EJB
I think if you do not implement EJB, and make a very simple code, for each request that a customer does, an object will be created and destroyed (not really, because its depends the JVM to destroy, garbage colletction, but its inaccessible to you) after sending the response to the client container. But again, depends on how you program, of which container ... I hope I have helped you in your inquiry.
I suggest reading the J2EE specification:
JSR-000342 EE 7 Specification
And a good book to read about EJB's: Enterprise JavaBeans 3.1, 6th Edition
By Andrew Lee Rubinger, Bill Burke
This was the answer that I was looking for. Thanks everyone who answered.
Does application server create new thread for each request from same user?
Web Container (Tomcat) spawns new thread for each request (not really, it uses thread pool for performance reasons).
For any request (doesn't matter who made it) a thread is obtained from the pool, the request is processed then the thread goes back to the pool.
Under IBM JVM we have faced an issue when multiple threads are trying to call Class.getAnnotation at the same time on different objects (but with the same annotation). Threads are starting to deadlock waiting on a monitor inside a Hashtable, which is used as a cache for annotations in IBM JVM. The weirdest thing is that the thread that is holding this monitor is put into 'waiting on condition' state right inside Hashtable.get, making all other threads to wait indefinitely.
The support from IBM stated, that implementation of Class.getAnnotation is not thread safe.
Comparing to other JVM implementations (for example, OpenJDK) we see that they implement Class methods in thread safe manner. IBM JVM is a closed source JVM, they do publish some source code together with their JVM, but it's not enough to make a clear judgment whenever their implementation of Class is thread safe or not.
The Class documentation doesn't clearly state whenever its methods are thread safe or not. So is it a safe assumption to treat Class methods (getAnnotation in particular) as a thread safe or we must use sync blocks in multi threaded environment?
How do popular frameworks (ex. Hibernate) are mitigating this problem? We haven't found any usage of synchronization in Hibernate code that was using getAnnotation method.
Your problem might be related to bug fixed in version 8 of Oracle Java.
One thread calls isAnnotationPresent on an annotated class where the
annotation is not yet initialised for its defining classloader. This
will result in a call on AnnotationType.getInstance, locking the class
object for sun.reflect.annotation.AnnotationType. getInstance will
result in a Class.initAnnotationsIfNecessary for that annotation,
trying to acquire a lock on the class object of that annotation.
In the meanwhile, another thread has requested Class.getAnnotations
for that annotation(!). Since getAnnotations locks the class object it
was requested on, the first thread can't lock it when it runs into
Class.initAnnotationsIfNecessary for that annotation. But the thread
holding the lock will try to acquire the lock for the class object of
sun.reflect.annotation.AnnotationType in AnnotationType.getInstance
which is hold by the first thread, thus resulting in the deadlock.
JDK-7122142 : (ann) Race condition between isAnnotationPresent and getAnnotations
Well, there is no specified behavior, so normally the correct way to deal with it would be to say “if no behavior is specified, assume no safety guarantees”.
But…
The problem here is that if these methods are not thread-safe, the specification lacks a documentation of how to achieve thread-safety correctly here. Recall that instances of java.lang.Class are visible across all threads of the entire application or even within multiple applications if your JVM hosts multiple apps/applets/servlets/beans/etc.
So unlike classes you instantiate for your own use where you can control access to these instances, you can’t preclude other threads from accessing the same methods of a particular java.lang.Class instance. So even if we engage with the very awkward concept of relying on some kind of convention for accessing such a global resource (e.g. like saying “the caller has to do synchronized(x.class)”), the problem here is, even bigger, that no such convention exists (well, or isn’t documented which comes down to the same).
So in this special case, where no caller’s responsibility is documented and can’t be established without such a documentation, IBM is in charge of telling how they think, programmers should use these methods correctly when they are implemented in a non-thread-safe manner.
There is an alternative interpretation I want to add: all information, java.lang.Class offers, is of a static constant nature. This class reflects what has been invariably compiled into the class. And it has no methods to alter any state. So maybe there’s no additional thread-safety documentation as all information is to be considered immutable and hence naturally thread-safe.
Rather, the fact that under the hood some information is loaded on demand is the undocumented implementation detail that the programmer does not need to be aware of. So if JRE developers decide to implement lazy creation for efficiency they must maintain the like-immutable behavior, read thread safety.
Let me give you the scenario.
Say that my first Activity that loads up, also creates a thread, which will run indefinitely in the background.
Now, if I move to another Activity, I assume that the thread that I initially created in the main activity will continue to run.
So, now to my main question - in order to manage this background thread from other Activities, is it safe to store a reference to that thread in a singleton object?
Yes and no. Theoretically, you will have no problem, but you must not allow references to escape.
Problems can arise from keeping the reference in the singleton object private, it must not pass the reference to anything else or allow access to it by anything else, or it can lose control.
Secondly, the thread created by your activity must not allow access to its member variables or allow references to them to escape.
A good book on this area is "Java Concurrency in Practice" by Brian Goetz
Actually where you need to be careful is if you have multiple class loaders. A Singleton is only a singleton if you are using the same class loader to load the class in. If you have multiple class loaders in your app running the same classes you will have another instance of the singleton in each.
Most standalone apps only use one classloader and therefore do not have any issues. If you have only one classloader then you will be fine.
I'm part of a team that develops a pretty big Swing Java Applet. Most of our code are legacy and there are tons of singleton references. We've bunched all of them to a single "Application Context" singleton. What we now need is to create some way to separate the shared context (shared across all applets currently showing) and non-shared context (specific to each applet currently showing).
However, we don't have an ID at each of the locations that call to the singleton, nor do we want to propagate the ID to all locations. What's the easiest way to identify in which applet context we're running? (I've tried messing with classloaders, thread groups, thread ids... so far I could find nothing that will enable me to ID the origin of the call).
Singletons are evil, what do you expect? ;)
Perhaps the most comprehensive approach would be to load the bulk of the applet in a different class loader (use java.net.URLClassLoader.newInstance). Then use a WeakHashMap to associate class loader with an applet. If you could split most of the code into a common class loader (as a parent of each per-applet class loader) and into the normal applet codebase, that would be faster but more work.
Other hacks:
If you have access to any component, you can use Component.getParent repeatedly or SwingUtilities.getRoot.
If you are in a per-applet instance thread, then you can set up a ThreadLocal.
From the EDT, you can read the current event from the queue (java.awt.EventQueue.getCurrentEvent()), and possibly find a component from that. Alternatively push an EventQueue with a overridden dispatchEvent method.
If I understand you correctly, the idea is to get a different "singleton" object for each caller object or "context".
One thing you can do is to create a thread-local global variable where you write the ID of the current context. (This can be done with AOP.) Then in the singleton getter, the context ID is fetched from the thread-local to use as a key to the correct "singleton" instance for the calling context.
Regarding AOP there should be no problem using it in applets since, depending on your point-cuts, the advices are woven at compile time and a JAR is added to the runtime dependencies. Hence, no special evidence of AOP should remain at run time.
#Hugo regarding threadlocal:
I thought about that solution. However, from experiments I found two problems with that approach:
Shared thread (server connections, etc) are problematic. This can be solved though by paying special attention to these thread (they're all under my control and are pretty much isolated from the legacy code).
The EDT thread is shared across all applets. I failed to find a way to force the creation of a new EDT thread for each applet. This means that the threadlocal for the EDT would be shared across the applets. This one I have no idea how to solve. Suggestions?