Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are static variables shared between threads?

My teacher in an upper level Java class on threading said something that I wasn't sure of.

He stated that the following code would not necessarily update the ready variable. According to him, the two threads don't necessarily share the static variable, specifically in the case when each thread (main thread versus ReaderThread) is running on its own processor and therefore doesn't share the same registers/cache/etc and one CPU won't update the other.

Essentially, he said it is possible that ready is updated in the main thread, but NOT in the ReaderThread, so that ReaderThread will loop infinitely.

He also claimed it was possible for the program to print 0 or 42. I understand how 42 could be printed, but not 0. He mentioned this would be the case when the number variable is set to the default value.

I thought perhaps it is not guaranteed that the static variable is updated between the threads, but this strikes me as very odd for Java. Does making ready volatile correct this problem?

He showed this code:

public class NoVisibility {       private static boolean ready;       private static int number;       private static class ReaderThread extends Thread {            public void run() {               while (!ready)   Thread.yield();               System.out.println(number);           }       }       public static void main(String[] args) {           new ReaderThread().start();           number = 42;           ready = true;       }   } 
like image 503
dontocsata Avatar asked Feb 08 '11 15:02

dontocsata


People also ask

Are static variables shared between threads C?

Each thread will share the same static variable which is mostly likely a global variable.

Are static variables shared?

Static variables are shared among all instances of a class. Non static variables are specific to that instance of a class. Static variable is like a global variable and is available to all methods. Non static variable is like a local variable and they can be accessed through only instance of a class.

Can we use static variable in multithreading?

static makes no sense in Multi-Threading.

Are instance variables shared between threads?

Given the architecture of the JVM, you need only be concerned with instance and class variables when you worry about thread safety. Because all threads share the same heap, and the heap is where all instance variables are stored, multiple threads can attempt to use the same object's instance variables concurrently.


1 Answers

There isn't anything special about static variables when it comes to visibility. If they are accessible any thread can get at them, so you're more likely to see concurrency problems because they're more exposed.

There is a visibility issue imposed by the JVM's memory model. Here's an article talking about the memory model and how writes become visible to threads. You can't count on changes one thread makes becoming visible to other threads in a timely manner (actually the JVM has no obligation to make those changes visible to you at all, in any time frame), unless you establish a happens-before relationship.

Here's a quote from that link (supplied in the comment by Jed Wesley-Smith):

Chapter 17 of the Java Language Specification defines the happens-before relation on memory operations such as reads and writes of shared variables. The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation. The synchronized and volatile constructs, as well as the Thread.start() and Thread.join() methods, can form happens-before relationships. In particular:

  • Each action in a thread happens-before every action in that thread that comes later in the program's order.

  • An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.

  • A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.

  • A call to start on a thread happens-before any action in the started thread.

  • All actions in a thread happen-before any other thread successfully returns from a join on that thread.

like image 128
Nathan Hughes Avatar answered Sep 22 '22 18:09

Nathan Hughes