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.
Related
Say I have class A which is not thread safe, and I want to launch a bunch of threads with class B, is passing a new instance of class A to each thread of class B a good design choice, since if I passed one instance of class A to all of them there would be concurrency issues?
#NotThreadSafe
class A {
...
}
class B extends Thread {
private A a;
B(A a) {
this.a = a;
}
}
class C {
public static void main(String [] args) {
for(int i = 0; i < 10; i++) {
A a = new A();
B b = new B(a);
b.start();
}
}
}
It pretty much depends on the characteristics of class A.
In general, passing creating an instance of A per thread will solve (not solve, but rather eliminate) concurrency issues.
Assuming class A has some internal state (otherwise class A itself is supposed to be thread safe), each thread B will read/update different fields in memory that belong to its "own" object of class A, so no concurrency issue here, unless...
A is very "heavy" object and creating it will have a big performance / memory impact.
Using design of object per thread won't meet the functional requirements of the product. For example, you have to share something between threads (somthing = some common state) because if one thread B, say, has done some work and has updated that internal state, another thread B should be able to benefit from (be able to read) that state otherwise it will do that work again or do it in a wrong.
Let's assume that you have overridden run in the B class. Your example doesn't make sense otherwise. (The start() call would invoke Thread::run which returns immediately. Ooops!)
Some terminology first.
A thread confined object is an object is an object whose state is accessible to one and only one thread.
If an object is thread confined, then it doesn't matter if the class is thread-safe or not.
(Depending on how broadly you define "state" of course. Lets assume that the object's state is the closure of the object that the object's methods may access. Or something like that.)
So what we have in your example is a non-thread-safe object a that is created in main and then used solely in a single child thread.
Prior to the start() call, each a is thread confined to the main thread. For this part of the program, thread-safety (of A) doesn't matter.
Once control reaches the child thread's run() method, each a is thread confined to the child thread. From then on, thread safety doesn't matter.
Now what about the start() call itself?
The Java Memory Model (JLS 17.4) specifies that there is a happens-before relationship between the call to start() in the main thread, and the call to run() in the child thread. This happens-before ensures that writes to the A or B instances or anything else made by the main thread prior to the start() call are guaranteed to be visible to the child thread on / after entering the run method body. This is a strong guarantee. Any compliant Java 5.0 or later implementation will behave this way, on any platform.
However, changes made to the A, etc in the main thread after the start() call are not guaranteed to be visible to the child. They may or may not be. If that happens, your code is likely to be broken. But the example code doesn't show it happening.
In summary, this approach is thread-safe. Whether it is "viable" depends on whether your design meets the requirements. For example, the B threads need to share state, this approach doesn't address that.
Finally, extending Thread is generally thought to be a bad idea. A better idea would be to instantiate plain Thread instances, passing them a Runnable as a constructor parameter. Alternatively, use an ExecutorService and let that take care of thread management.
There is a big difference between using a single instance and a new instance each time. (Eg if the class represents a Person then, it's the difference between the same person or a different one every time. This makes the program outcome different between circumstances and this question therefore doesn't make sense.)
If we assume the class holds no data and therefore the program outcome will not change whether or not a single instance or multiple are used, then
a good design choice, since if I passed one instance of class A to all
of them there would be concurrency issues
it would be a terrible design choice and not solve any concurrency issues, as the external data each class instance works on will still be the same and the threads will fight over the data.
To fix concurrency issues you must use synchronization.
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.
something about static:
instances of class share static method
the similar questions:
Java: when to use static methods
What does the 'static' keyword do in a class?
I am confusing about:
static method just have only one memory block?
if i use static method in multithreading, will it block?
I am confusing about:
static method just have only one memory block? if i use static method
in multithreading, will it block?
The static keyword in Java simply means "without regard or knowledge of any particular instance of an object."
An instance method can use this to access the fields of its associated instance, but a static method has no associated instance and so this makes no sense.
In multithreading, thread safety involves protecting the consistency and integrity of mutable data. Because objects encapsulate the state of their instance fields, instance methods only need to be concerned about thread safety in those circumstances in which more than one thread will be accessing the same object.
So while thread confinement of an object is a valid thread safety policy for instances of a class, this same reasoning is invalid for static methods because they have no instance.
This has nothing to do with memory blocks at all. It just has to do with access. An object instance is accessed through a reference. If the reference is thread confined, then the object to which that reference points will always be thread safe. But any thread anywhere that can access your class can potentially get to its static members because no reference to an instance is needed to use them.
Static methods are non-blocking by default. You can implement your own synchronization/thread safety policy and have your static method block if you wish.
Each thread has its own stack space, each time a thread calls a method (static or virtual) that call allocates a stack frame, which holds local variables. nothing about this is specific to static methods.
Static methods can be called concurrently by multiple threads, unless you specifically do something to thwart that, such as requiring that the caller acquire a lock (such as using the synchronized keyword).
Static methods are good for cases where there is no shared state. They may be ok in cases accessing or modifying threadsafe shared state, depending on what level of concurrency is needed and how efficient the threadsafe things being accessed are.
Look out for bottlenecks. Putting the synchronized keyword on a static method may be a problem as that limits your application to calling it with only one thread at a time. Alternative strategies including using atomic objects, using threadsafe data structures designed for high concurrency, or using thread confinement may be preferable to locking.
static method just have only one memory block?
No, methods don't have memory blocks. Threads executing those methods do. Each thread will have it's own memory on the stack where it stores all the method arguments and variables.
if i use static method in multithreading, will it block
A thread cannot access the memory of another thread, but if there is some resource that belongs to all instances and is supposed to be accessed sequentially, then you can synchronize or lock the static method, thus making it a blocking one. Otherwise, no.
Even though there is one instance of a static method, each thread gets its own stack-frame, which means each thread can exercise the same method but in a separate "world" from other threads.
Threads always get their own stack, even for a singleton class (one instance):
so, when to use static methods and when to not?
The main reason for not using static methods everywhere is that they are difficult to unit-test barring manipulating compiled code (Powermock), so static methods should have no dependencies that would require mocking, i.e. the test calls the real method with an input and asserts the output, verbatim, in two steps.
Non-static methods allow you to isolate your test solely to that method by stubbing, mocking, or spying on objects that the method depends on.
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.
In my recent interview by explaining a situation they asked if the process is thread-safe
There are two synchronized methods one is static and other is not static i.e., non-static Method A and static Method B. These two methods access a shared data.
Now thread A calls non-static method A and thread B is calls static method B. Is this thread safe and explain y?
No, it's not thread-safe. For it to be thread-safe the different threads have to access the shared data using the same lock, but the two methods use different locks. Putting synchronized on a static method uses the class as a lock, putting synchronized on an instance method uses the object as a lock.
If the threads use different locks then neither thread is blocked, and both can access or modify the data concurrently. Even if the threads are only accessing data, and neither modifies it, locking would assure memory visibility. Without the shared lock you can't rely on that visibility. Unrestricted concurrent access would be safe only if the data is immutable and is already safely published.
Assuming the shared data has to be mutable, the fix would be for both methods to use the same lock. You can always specify your own lock if you use a synchronized block (rather than adding synchronized to the method), so the instance method could use:
public void yourInstanceMethod() {
synchronized(WhateverYourClassIs.class) {
// code accessing shared data
}
}