Propagate threadLocal variable - java

I am running into this particular issue and was wondering if anyone has come across this particular issue. I have a method: methodA() - this will create a ThreadLocal called "temp" if it doesn't exist, if the ThreadLocal exists, it'll return that ThreadLocal variable (IE: "temp" in this scenario)
Basically the scenario I am running into is this: I call methodA() - (I create the ThreadLocal variable "old_temp") Then I call the method:
CompletableFuture.supplyAsync( () ->{ThreadContext.put("RequestId", requestId); methodB();}, iotaInvokerService).handleAsync(methodC());
Where methodB() is from another team's library and methodB() invokes methodA().
When methodB() invokes methodA(), I want methodA() to return the ThreadLocal variable "old_temp" that was initially created when methodA() was first called. However, when methodB() invokes methodA(), instead of returning the "old_temp" ThreadLocal variable, it creates a completely new ThreadLocal variable to use, which I do not want. When methodB() invokes methodA(), I want it to return "old_temp". Could anyone be able to help me with this scenario?
IE, my belief is that when CompletableFuture.supplyAsync is called with an executorService, it creates a new Thread to which the ThreadLocal variables context are not passed on, which seems to be the problem.
I saw Propagating ThreadLocal to a new Thread fetched from a ExecutorService but I still wasn't sure/still confused on how to apply it to my scenario. I think the thing is that I know what ThreadLocal variable is it that I want, but I am not too sure.

ThreadLocal provides thread-local variables in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. If a computation is started by a thread and continued by another one, then using ThreadLocal seams inappropriate.
If you rely on a library like project reactor, then you can use a Context that is automatically is propagated...
Another option is to use global values (or a singleton that allow access to ...)

Related

Does every asynchronous call in spring boot creates separate copy of every variable?

I want to clarify three confusions here.
Question 1) My first question is that if we have a Java class in spring boot and we have one logger object at class level. Now inside this class in some function we have async call. Now when this asynchronous call will start . will it creates separate copy of all needed variables, in its stack ? or it will use same objects created at class level in main thread ?
For example imagine that we have some logger object at class level, which we are using for logging in main thread. Now if we access it in our async thread call in some method in same class. Will this async call use same logger object of main object or it will have its own new copy of logger object in its stack ?
Question 2) second questions is followed by answer of first questions, if async call will have separate copy of objects initialized in parent thread, then why exception occurs when both threads try to access same object at same time, as both have separate copies of same object.
Question 3) and if scope of any bean is singleton, still new copy of its object will be created in async call ? or same object will be shared among both main thread and async call ?
The async call invokes a method, all local variables defined in that method exist on the stack frame of the method call. So those are copies that belong to that method invocation and they are accessed only by the thread executing the async method.
Instance variables and class variables, like the logger, are the same as for synchronous calls, they are not copied. If your async method references a repository, and another method references that same repository, both are calling the same object.
The other questions seem based on a misunderstanding of this first issue.
A spring component that you're calling the method on should not have conversational state, the instance members should be other spring components. Loggers are designed to be shared between threads.

A synchronized method call in Java is ignoring an initialization Flag (spring)

Sorry for the bad title, but the explanation will be very simple.
I have, on a Service on Spring this method:
private static boolean initialized = false;
#PostConstruct
public void onPostConstruct() {
synchronized (MyClass.class) {
if (!initialized) {
// do some init
startThread();
initialized = true
}
}
}
JavaSE-wise, I'm 100% confident that there can't be more than one thread started by the call startThread(). It has something to do with the loading of classes in Spring, because there's more than one thread. I see it in the logs.
I cannot reproduce the bug on my computer, only on the server, and I don't have access, so, I ask here. If someone can float me some light! thanks
Your code is definitely thread safe. Multiple calls to startThread() will only possible be if your class is loaded more than ones by different ClassLoaders.
I'm not a Spring expert but according to the answers of this question it is possible to specify a ClassLoader for each ApplicationContext. If your class should be used in multiple ApplicationContexts with different ClassLoader instances it would be possible, that there exist two class objects for your class. Since you synchronize by the class object, calls to onPostConstruct() would only be mutually exclusive for one instance of the class.
To verify that your code is called for multiple instances of the class, extend your code with some logging and log the return value of MyClass.class.getClassLoader().
During execution, static variable value are initialised to class but not instance, so if you have a any one instant of your Service changed the initialized to true, then it changed to true forever for all instance.
for #PostConstruct, it will be called when the constructor is called, and for Spring server, all the class will be constructed as bean during startup, so this method should be called once, so before the start of service, the flag already changed to true.
I suggest you to create an other method to change the flag rather than in post construct.
I guess the issue with the order of execution between startThread() method and the reassignment of initialized variable.
First Execution: startThread() method, is it starting a thread ??
at the same time initialized reassigned to true;

ThreadLocal versus Member Variable in a Thread in Java

Can we get back reference to a member variable of a Thread like the way we get for ThreadLocal?
For example, lets say we use a counter variable to counter amount of requests processed by the Thread in a ThreadLocal variable. Consider that we are using a ThreadPool Executer for reusing threads. Now every Thread keeps a reference to a ThreadLocal counter variable and it can increment its own copy after every request.
In a similar manner if i have a Member variable inside a Runnable, can i get back a reference to it? The Thread is anyway being reused.
if i have a Member variable inside a Runnable, can i get back a reference to it?
When you say "a Runnable", you're talking about some object that implements the Runnable interface. There is nothing magic about Runnable and there is nothing magic about a run() method.
The member variables of your Runnable object are just like the member variables of any other object, and your code accesses them in the same way.
P.S., Usually, when you see ThreadLocal in a program, it means
The program used to be single-threaded,
It keeps a lot of its state in static variables,
Somebody added multi-threading as an after-thought, and
It makes sense for some of that static state to be duplicated for each thread.
I would almost never use ThreadLocal in a new program, because I try hard not to write any code that depends on static variables, and if you're using ThreadLocal for non-static data, you're probably making your program way more complicated than it needs to be.

Can Java's Threadlocal be applied to a non-static field, if yes, how?

ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This made little sense to me as each thread's stack is confined to that thread alone. So it is already 'threadlocal', right ?
Why then do we need ThreadLocal ? - On further reading, I confirmed my assumption from various sites (a majority of which fail to provide these facts or contradict each other) that this is indeed applicable for static fields.
Which does make sense.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields ? (I came across some sites that say 'ThreadLocal' is "mainly" used for static fields; even https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html uses the word "typically")
I think that this Question is based on a false premise.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This is not what "global" really means. Global really means accessible to the entire program without any qualification. And in fact, Java doesn't have true global variables. The closest it has is "public static" fields ... which are accessible with qualification.
But back to the Question ...
A threadlocal variable is available to a method if two conditions are satisfied:
The method call must be on the correct thread. (If it is on a different thread, it sees a different variable.)
The method must be able to get hold of the ThreadLocal object that effectively "declares" the thread local variable (in any thread).
Does the 2nd condition imply that the "declaration" is global?
IMO, no. For two reasons.
Global variables in the conventional sense have only one instance. A thread local has a distinct instance for each thread.
The fact that the ThreadLocal is accessible to a specific method does not make it accessible to any method. The normal (and good practice) usage pattern for a ThreadLocal is to hold the object reference in a private static variable. That means that methods in the same class can use the corresponding thread local variable instances ... but methods in other classes can't.
Now it is possible to put the reference to ThreadLocal in a public static variable, but why would you do that? You are explicitly creating a leaky abstraction ... which is liable to cause problems.
And of course, you can do what #Radiodef's answer shows; i.e. create a thread local whose instances are only accessible from methods on a specific instance of a specific class. But it is hard to understand why you would want / need to go to that level of confinement. (And it is liable to lead to storage leaks ...)
Short answer: if you don't want your thread local variables to be accessible, restrict access to the ThreadLocal object.
Only local variables are on a thread's stack.* Static variables and instance variables both live on the heap. If we wanted to, we could also just pass a ThreadLocal around by itself without it ever living inside an object or class.
We could view ThreadLocal as a local variable which could be accessible at any point in time.
Normal local variables are destroyed when the scope they are declared in returns, but a ThreadLocal can live anywhere.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields?
We can make one up...
interface Dial {}
class Gadget {
ThreadLocal<Dial> d = new ThreadLocal<>();
}
class Gizmo implements Runnable {
Gadget g;
Gizmo(Gadget g) {
this.g = g;
}
public void run() {}
}
{
Gadget g = new Gadget();
new Thread(new Gizmo(g)).start();
new Thread(new Gizmo(g)).start();
}
Both threads share the same instance of Gadget but has their own local Dial.
Why then do we need ThreadLocal?
The truth is we don't need ThreadLocal very often, if at all.
* Only local variables are on a thread's stack except in the case of a theoretical optimization the JVM is allowed to do where objects can be stack allocated. We would never find out about this if it happened because it would not be allowed to change the behavior of the program. If an object is shared between threads, it's on the heap.
static ThreadLocal<Whatever> threadLocal;
Declares a field that points to an instance of class ThreadLocal. Each Thread has a Map<ThreadLocal<?>, Object> that associates instances of ThreadLocal with the value the corresponding "thread local variable" has for this Thread. That is, each ThreadLocal instance identifies a "thread local variable", and as far as the JVM is concerned, ThreadLocal is a class like any other.
Usually, when we need a "thread local variable", we only need a single one, and therefore create only a single ThreadLocal instance, which is often kept in a static field for convenient access.
If we need a new "thread local variable" for every instance of the host object, we could simply create a new ThreadLocal instance for every host object, and store in an a non-static field. Off hand, I can't think of a case where this is the simplest solution, but we could do it.
Threadlocal is a container for a set of variables each one of which is only available to one thread, ie it provides an instance of the contained class for each thread. So the ThreadLocal object is globally available (spending on permissions) but each instance of the contained class is only locally available to the thread.
This means that it needs to be initialized and destroyed for each thread slightly differently but in all other ways it is the same as any other variable.
Note : The point of destroying instances is to prevent memory leaks or leakage of state between independent invocations on the same thread if threads are being drawn from a pool.
Thread local variables are often used to provide a thread safe option for storage where there is no need for communication between threads. One such example is to define a new scope in CDI where that scope will exist wholly within a single thread (eg you could define an asynchronous request scope).
As such there is no need to restrict it to static or non-static variables as long as it is accessible where it is needed. In a default java environment Static variables are a convenient way of providing such access but in CDI a Singleton bean can provide the same level of access with many advantages.
In the injected singleton case the singleton bean would contain a nonstatic reference to the ThreadLocal and provide services to access the instances contained therein. Both the references to the injected singleton and the singleton's reference to the ThreadLocal would be non static.

Java thread safety in singleton scoped class methods

So I have a Singleton class and in it a non-static public method that is called by multiple threads. In the non-static method I have local references to objects created by a Stored Procedure which I surmise means the 'new' keyword gets called somewhere.
1 public void someMethod(SomeObjectParameter parameter) {
2
3 Thing thingOne = synchornizedStoredProcedureCall():
4 doSomethingWith(thingOne);
5 doSomethingElseWith(thingOne);
6
7 }
Currently lines 3 through 5 are in a synchronized code block which I would like to reduce down to just having the stored procedure call as synchronized.
So... Say we have two threads, Thread1 and Thread2. Thread1 is about to execute line 3 and Thread2 is about to execute line 4. Since this is a local reference, will each thread maintain a different reference or will synchornizedStoredProcedureCall overwrite the reference to thingOne as doSomethingWith is about to use it?
What if thingOne is declared final or if I made it immutable?
will each thread maintain a different reference or will synchornizedStoredProcedureCall overwrite the reference to thingOne as doSomethingWith is about to use it?
The different threads have different stacks. The thingOne is stored in the per-thread stack so cannot be overwritten by the other thread. You also need to make sure that the synchornizedStoredProcedureCall() is returning a different instance of Thing each time and not a static or instance variable. Both threads need to be working on different Thing instances.
As long as the doSomethingWith(...) and doSomethingElseWith(...) calls are thread safe and only work with thingOne argument and constants (etc), protecting just the synchornizedStoredProcedureCall() should be fine.
As #Marko points out, without seeing the Thing class, we cannot be guaranteed that it is thread-safe and not storing internal state.
The answer depends on a lot of details that you haven't presented. Many details about the Thing class matter: it could have some internally shared state that may not be thread-safe (see the Flyweight design pattern). These facts must be documented in the class Javadoc; otherwise it would be very difficult to find it out from source code.
Thingone is thread safe anyway as it is declared threadlocal on the stack. If thingone was an instance variable not declared within a method, you would have problems; but it isn;t - so you don't.
your thingOne is local variable. it is thread safe. Each thread gets its own copy of locals.
You need to be sure that thingOne is not shared. Even though it is returned from a synchronized method, if it is a member of the singleton returned from synchornizedStoredProcedureCall , your implementation is no longer thread safe.
Each thread will maintain a different reference. That would be even the case if someMethod was static.
You still have to be sure that the Thing instances are thread safe themslef. E.g. the Thing class doesn't have static fields nor the two Thing instance have a non-static field pointing to the same object, or if they do they handle them in a thread safe way.

Categories