One of my java static method is accessed by multiple threads . Do I need to synchronize the method explicitly by synchronized keyword?.
Sometime back I read in a book which states that
static method is implicitly thread safe as the method is not object specific
.
Well known example is , Singleton implementation. In which getInstance() is static and do we need to mark this as synchronized as well?
public synchronized static Logger getInstance() {
if( instance == null ){
instance = new Logger();
}
return instance;
}
Thanks
A data type or static method is threadsafe if it behaves correctly when used from multiple threads, regardless of how those threads are executed, and without demanding additional coordination from the calling code.
Solution 1. No, static functions are not inherently thread-safe.
It is well know that static methods with Immutable Objects as parameters are thread safe and Mutable Objects are not.
Yes, we can have private methods or private static methods in an interface in Java 9.
I think that as long as all variables are local variables it doesn't matter whether the class is static or instance. They have their own stack trace and hence are thread safe. A method parameter is local, and if its type is mutable, it may well not be thread-safe.
Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread. So all the methods are thread safe until they change the state of some static variable.
When a thread is already working on an object and preventing another thread on working on the same object, this process is called Thread-Safety. There are four ways to achieve Thread Safety in Java. These are: Using Synchronization.
A static method is one that you can call without reference to an object (i.e., an instance of the class). It sounds like you've got threads, static vs. instance methods, and multiple copies of code all mixed up in your head. Let me try to clear things up.
static
modifier and thread safety are two distinct matters.
You are in a defacto thead-safety case only when you don't have any race condition.
Having no race condition for a method means that :
either the access to the method are done by a single thread
or by concurrent threads but only for reading access.
These two things have zero relation with the fact that the method be static or not.
For example in this code :
public static Logger getInstance() {
if( instance == null ){
instance = new Logger();
}
return instance;
}
It is thread safe defacto if the application is mono threaded.
But it is not the case if it is accessed concurrently by threads as the method doesn't make only reading access.
In this case, you need to synchronize the access to the method.
As a side note, the Bill Pugh idiom singleton spares the use of a synchronized method to implement a singleton.
You can indeed implement it by taking advantage of static initialization done by the JVM as the class is loaded :
public class SingletonBillPughWithEagerCreation {
// executed as soon as the SingletonBillPughWithEagerCreation class is loaded by the classLoader
private static SingletonBillPughWithEagerCreation instance = new SingletonBillPughWithEagerCreation();
private SingletonBillPughWithEagerCreation() {
}
public static SingletonBillPughWithEagerCreation getInstance() {
return instance;
}
}
No, it is not.
The sentence you quote means that the static method is not object specific and, because of the local variable is saved in thread environment, it can only be accessed from the local execution of the thread itself. But in a static method you can access to a static field or an object shared by multiple thread, in that case you are not dealing with a local variable, but with something shared among multiple object.
In other word, since the execution is thread safe, the access to a field of an object is shared to all threads that has access to the object. In that case you have a concurrency problem which have to be handled with the synchronized
keyword. With synchronized keyword you make a statement accessible from only one thread per time.
class MyObject{
static MyType mySharedObject; //if you access this in static methos you are not safe until you sync the access
public static void myMethod(){
int localVar; //that is safely accessed
mySharedObject.setSomething(pippo); //that is not safe in multi thread environment.
}
}
A method can be considered thread-safe if simultaneous calls from multiple threads will not create a situation, where any memory space is written by one thread, and simultaneously written/read by another thread at the same time.
This example shows a function that if called by multiple threads can cause issues:
void doThreadNonsense(int input) {
this.myValue = input;
if (this.myValue > 9000) System.out.println("It's over 9000!");
}
Because here a value is first written, then read by multiple threads, and it could happen that Thread A writes a 5, then Thread B writes a 9000, and then Thread A outputs the sentence, because the value is now > 9000, despite the input of 5.
With however just a minor change this function becomes thread-safe:
void doThreadNonsense(int input) {
this.myValue = input;
if (input > 9000) System.out.println("It's over 9000!");
}
Now the value is only written by multiple threads, but since writing an int happens atomically on any 32-bit (or higher) machine, myValue
is only written by one thread or another, but never by both at the same time. This example shows how closely you need to check what your code is doing to figure out whether or not it is thread-safe.
If you take a static method it can - as above - also be not thread-safe:
static int myValue;
static void doThreadNonsense(int input) {
myValue = input;
if (myValue > 9000) System.out.println("It's over 9000!");
}
However in most cases static functions do not write on static variables (this isn't considered clean code by OOP design patterns), and if you don't access anything outside the scope of the method, the code is automatically thread-safe, because all used memory locations are local to the current thread only.
static void doThreadNonsense(int input) {
if (input> 9000) System.out.println("It's over 9000!");
}
So your book should have said: "Static methods that follow the clean code paradigm tend to be thread-safe."
This is however not at all helpful, and completely misses the point why something is thread-safe and other things are not. Take the following example, that is surprisingly (to some) thread-safe, despite that it violates many of the "clean threading" rules:
static final int[][] matrix = new int[N][M];
static void fillMatrixColumn(final int n) {
for (int m = 0; m < M; ++m) {
matrix[n][m] = calculateValue(n, m);
}
}
public static void main(String[] args)() {
IntStream.range(0, N)
.parallel()
.forEach(this::fillMatrixColumn);
printMatrix(matrix);
}
No synchronized, no locking, but a lot of happy writing from multiple threads to the same data structure. This is still thread-safe, because at no point two threads are simultaneously writing to/reading from the same memory location.
There are some answers explaining why it's not thread safe, but to answer your quote
static method is implicitly thread safe as the method is not object specific
The JVM instruction invokestatic for static methods documents that
If the method is synchronized, the monitor associated with the resolved Class object is entered or reentered as if by execution of a monitorenter instruction (§monitorenter) in the current thread.
Which means that static methods are not inherently thread-safe in a concurrent environment, because there is a difference between synchronized
and non-synchronized
static methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With