Are static variables shared between threads? Are static variables shared between threads? multithreading multithreading

Are static variables shared between threads?


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.


He was talking about visibility and not to be taken too literally.

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.

This article presents a view that is consistent with how he presented the info:

First, you have to understand a little something about the Java memory model. I've struggled a bit over the years to explain it briefly and well. As of today, the best way I can think of to describe it is if you imagine it this way:

  • Each thread in Java takes place in a separate memory space (this is clearly untrue, so bear with me on this one).

  • You need to use special mechanisms to guarantee that communication happens between these threads, as you would on a message passing system.

  • Memory writes that happen in one thread can "leak through" and be seen by another thread, but this is by no means guaranteed. Without explicit communication, you can't guarantee which writes get seen by other threads, or even the order in which they get seen.

...

thread model

But again, this is simply a mental model to think about threading and volatile, not literally how the JVM works.


Basically it's true, but actually the problem is more complex. Visibility of shared data can be affected not only by CPU caches, but also by out-of-order execution of instructions.

Therefore Java defines a Memory Model, that states under which circumstances threads can see consistent state of the shared data.

In your particular case, adding volatile guarantees visibility.