Are non-synchronised static methods thread safe if they don't modify static class variables?

63,528

Solution 1

This method is 100% thread safe, it would be even if it wasn't static. The problem with thread-safety arises when you need to share data between threads - you must take care of atomicity, visibility, etc.

This method only operates on parameters, which reside on stack and references to immutable objects on heap. Stack is inherently local to the thread, so no sharing of data occurs, ever.

Immutable objects (String in this case) are also thread-safe because once created they can't be changed and all threads see the same value. On the other hand if the method was accepting (mutable) Date you could have had a problem. Two threads can simultaneously modify that same object instance, causing race conditions and visibility problems.

Solution 2

A method can only be thread-unsafe when it changes some shared state. Whether it's static or not is irrelevant.

Solution 3

The function is perfectly thread safe.

If you think about it... assume what would happen if this were different. Every usual function would have threading problems if not synchronized, so all API functions in the JDK would have to be synchronized, because they could potentially be called by multiple threads. And since most time the app is using some API, multithreaded apps would effectively be impossible.

This is too ridiculous to think about it, so just for you: Methods are not threadsafe if there is a clear reason why there could be problems. Try to always think about what if there were multiple threads in my function, and what if you had a step-debugger and would one step after another advance the first... then the second thread... maybe the second again... would there be problems? If you find one, its not thread safe.

Please be also aware, that most of the Java 1.5 Collection classes are not threadsafe, except those where stated, like ConcurrentHashMap.

And if you really want to dive into this, have a close look at the volatile keyword and ALL its side effects. Have a look at the Semaphore() and Lock() class, and their friends in java.util.Concurrent. Read all the API docs around the classes. It is worth to learn and satisfying, too.

Sorry for this overly elaborate answer.

Solution 4

Use the static keyword with synchronized static methods to modify static data shared among threads. With the static keyword all the threads created will contend for a single version of the method.

Use the volatile keyword along with synchronized instance methods will guarantee that each thread has its own copy of the shared data and no read/ writes will leak out between threads.

Share:
63,528
Sled
Author by

Sled

A Java Developer who has worked at places ranging from a Fortune 100 company to a small start-up. Using Java for over 20 years.

Updated on July 08, 2022

Comments

  • Sled
    Sled almost 2 years

    I was wondering if you have a static method that is not synchronised, but does not modify any static variables is it thread-safe? What about if the method creates local variables inside it? For example, is the following code thread-safe?

    public static String[] makeStringArray( String a, String b ){
        return new String[]{ a, b };
    }
    

    So if I have two threads calling ths method continously and concurrently, one with dogs (say "great dane" and "bull dog") and the other with cats (say "persian" and "siamese") will I ever get cats and dogs in the same array? Or will the cats and dogs never be inside the same invocation of the method at the same time?

    • 象嘉道
      象嘉道 about 12 years
      another thread on this issue: stackoverflow.com/questions/8015797/…
    • Sled
      Sled about 12 years
      That is a different question, this is whether static method invocation is thread safe, not whether arrays are.
  • Sid
    Sid about 13 years
    Correct answer. Method level variables are replicated in each thread execution stack.
  • Sled
    Sled about 13 years
    "If you think about it... assume what would happen if this were different. Every usual function would have threading problems if not synchronized, so all API functions in the JDK would have to be synchronized, because they could potentially be called by multiple threads." Good point!
  • Sled
    Sled about 13 years
    @Konrad_Garus The question here was along the lines of whether local variables constitute shared state or not, or whether the stack for a static method was per thread or shared.
  • bestsss
    bestsss about 13 years
    technically the method is to be inlined and the parameters will be CPU registers. Nonetheless the answer is correct
  • Jörn Horstmann
    Jörn Horstmann about 13 years
    The stack is of course local to the current thread, but you can have references to shared objects on that stack. This is not an issue in the example since Strings are immutable, but a method that modifies a passed parameter can have thread safety issues if this passed object is accessible from multiple threads.
  • Sled
    Sled over 12 years
    The question was if a static method call would ever see the arguments of another call to the same method from another thread. The answer is a resounding "no!". This, I knew but wanted to be able to prove to dubious coworkers.
  • som-snytt
    som-snytt over 11 years
    Why was this response down-voted? The point, not contributed by the other answers, is that mutability might be in-bound or out-bound. If you return a mutable, then you're not threadsafe. The question does not pose its question as narrowly as the comment suggests; the extended question after the code sample could have been expressed in code, perhaps as a unit test. But I do sympathize with trying to convince coworkers. "They don't believe me, or my test code, or Josh Bloch, but maybe they'll accept an answer on SO."
  • Rafay
    Rafay over 11 years
    As @TomaszNurkiewicz mentioned, if we pass a mutable object reference, we can get into race conditions. Does this holds true even if the method doesn't change the object in any way? I mean, will it still be classified as a race condition because the object was mutable? And what if we add the final keyword to the parameters?
  • grep
    grep about 9 years
    What if I pass class object in the method? Will the varaible in the stack or heap?
  • Warren Dew
    Warren Dew almost 7 years
    "A method can only be thread-unsafe when it changes some shared state." No, it can also be thread unsafe if it merely accesses shared state without changing it. Unsynchronized access to a mutable object can access inconsistent state if the object is being mutated by another thread, even if the other thread is properly synchronized. Both threads need appropriate synchronization for thread safety to be maintained.