Static variables and multithreading in java

后端 未结 7 1681
心在旅途
心在旅途 2020-12-02 13:31

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?

相关标签:
7条回答
  • 2020-12-02 14:03

    Actually class variable corresponds to the class, in it shares only single memory, so changes made by each instance of class can change the class variable.

    0 讨论(0)
  • 2020-12-02 14:06

    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).

    0 讨论(0)
  • 2020-12-02 14:12

    As SLaks suggested its one per JVM, but beware that two threads holding lock on same static reference will block each other, reason being there is only one such reference per vm. But they wont block threads referring to instance variables.

    0 讨论(0)
  • 2020-12-02 14:19

    Static fields gave one value per class-loader.

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

    0 讨论(0)
  • 2020-12-02 14:21

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题