Static variables and multithreading in java

31,305

Solution 1

Static fields gave one value per class-loader.

If you want a per-thread value, make a static ThreadLocal<T>.

Solution 2

Is a static member of a class present as only a single instance per process or thread?

static fields have one value per class-loader but I think the meat of your question is in the following:

each thread has its own copy of the static member variable of the class

This is correct although the devil is in the details. Each thread may have it's own copy of the field in it's own local memory space/cache unless the field has been marked with volatile which forces the field to be surrounded with a memory barrier which causes a memory synchronization on each access/update.

Without volatile, any updates and reads to a static field will be made to local thread storage and only updated whenever a thread crosses a memory barrier. Without the memory barriers, there are no guarantees around the order of data operations and when the updates will be shared with other threads.

Here's a decent page about the Java memory model and a good overview of some of the challenges.

Solution 3

There is one copy of static variable per class-loader that loaded this class. This more-or-less means per-process, however you need to be aware of the difference.

E.g. when two web-apps have the same class bundled, the class will be loaded twice, thus having two copies of the same static field.

If you need a variable having independent value on a thread basis, have a look at ThreadLocal.

Solution 4

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html

Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated. A field defining the number of gears for a particular kind of bicycle could be marked as static since conceptually the same number of gears will apply to all instances. The code static int numGears = 6; would create such a static field. Additionally, the keyword final could be added to indicate that the number of gears will never change.

Threads have no bearing on this. (The classloader on the other hand does. If you're using multiple classloaders in your application, however, you are probably at a point where you understand that).

Solution 5

The issue with threading is this: The "10,000 foot" view of Java memory is that there is one single chunk of memory that is shared by all classes, all objects, all class loaders, and all threads in the running JVM -- whatever is accessible from one place in the code is accessible everywhere else (given an appropriate reference). The only exception is registers and the execution stack, which are conceptually on a per-thread basis.

This works pretty darn well with a single processor, where threads take turns executing in a single set of registers and ALUs and such. But most modern computers have multiple processors, so that several threads can execute literally at the same time. If these processors had to all reference the same physical memory then (based on real-life experience) you'd only be able to get about 1.5x performance improvement with 4 processors, and it would degenerate from there.

So "cache" is used, so that each processor has its own little private copy of bits and pieces of the larger memory. Most of the time the processors are addressing entirely different areas of memory, so this works fine, but occasionally (as when dealing with some "shared" object) they must "fight" over the same set of bytes.

The solution is to establish protocols so that no two processors will attempt to modify the same storage locations at the same time (or nearly the same) and to assure that one processor's changed get "flushed" to main store and other processors be made aware of the changes and advised to reload their view of the modified data.

But it's (incredibly) inefficient to do this after every operation (and, quite frankly, hardware designers have dodged the issue to a significant degree and pushed more of this work onto the software than is probably justified). So schemes are used such that the flush and reload of data only occurs on certain "boundaries", or when certain special types of references are done.

Note that all this has absolutely nothing to do with whether a variable is "static" or not, nor does it really have to do with whether objects are "immutable". It's inherent in the modern multi-processor hardware architecture, combined with the Java thread model.

Share:
31,305
shawn
Author by

shawn

Updated on December 02, 2021

Comments

  • shawn
    shawn over 2 years

    Is a static member of a class present as only a single instance per process or thread? Meaning does each thread has its own copy of the static member variable of the class?

    My guess is per process, am I correct?