Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread Safe - final local method variable passed on to threads?

Will the following code cause same problems, if variable 'commonSet' of this method was instead a class level field. If it was a class level field, I'll have to wrap adding to set operation within a synchronized block as HashSet is not thread safe. Should I do the same in following code, since multiple threads are adding on to the set or even the current thread may go on to mutate the set.

public void threadCreatorFunction(final String[] args) {
    final Set<String> commonSet = new HashSet<String>();

    final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                commonSet.add(newValue());
            }
        }
    };

    new Thread(runnable, "T_A").start();
    new Thread(runnable, "T_B").start();
}

The reference to 'commonSet' is 'locked' by using final. But multiple threads operating on it can still corrupt the values in the set(it may contain duplicates?). Secondly, confusion is since 'commonSet' ia a method level variable - it's same reference will be on the stack memory of the calling method (threadCreatorFunction) and stack memory of run methods - is this correct?

There are quite a few questions related to this:

  • Why do variables passed to runnable need to be final?
  • Why are only final variables accessible in anonymous class?

But, I cannot see them stressing on thread safe part of such sharing/passing of mutables.

like image 915
haps10 Avatar asked Aug 06 '12 07:08

haps10


People also ask

Are local variables in method thread-safe?

On its stack(basically thread stack), local primitives and local reference variables are stored. Hence one thread does not share its local variables with any other thread as these local variables and references are inside the thread's private stack. Hence local variables are always thread-safe.

Are local variables shared between threads?

Tip: Unlike class and instance field variables, threads cannot share local variables and parameters. The reason: Local variables and parameters allocate on a thread's method-call stack. As a result, each thread receives its own copy of those variables.

Can static variables be shared between threads?

Static variables are indeed shared between threads, but the changes made in one thread may not be visible to another thread immediately, making it seem like there are two copies of the variable.

How do you make a local variable thread-safe in Java?

Stack Memory and Threads Secondly, it stores local primitives and local object references on the stack. In addition, it's important to realize that every thread, including the main thread, has its own private stack. Therefore, other threads do not share our local variables, which is what makes them thread-safe.


1 Answers

No, this is absolutely not thread-safe. Just because you've got it in a final variable, that means that both threads will see the same reference, which is fine - but it doesn't make the object any more thread-safe.

Either you need to synchronize access, or use ConcurrentSkipListSet.

like image 107
Jon Skeet Avatar answered Sep 18 '22 06:09

Jon Skeet