• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

All Static code thread safety

 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello

I have a static variable and few static methods are accessing it from different threads.
As designed, there is no non static method that is going to access it.

Is this static variable thread safe?

Thanks in advance,

Amit
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13071
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nothing magic about static code, the same rules as for "Thread Safety" in all other objects also apply here.

Bill
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
mahajan amit wrote:
Is this static variable thread safe?

No, it is not thread safe. you can see this behavior to write one java program
1.start two thread on single object
2. declare one static int in that object
3. and loop like below in your run()

you need proper synchronization for above code.

<edit>William beaten me ;)</edit>
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Seetharaman Venkatasamy wrote:


Code like this can actually quite easily give the appearance of thread-safety, even though it's not thread-safe, because the work a thread has to do is so much shorter than a typical time slice. The println() can help break that up, but in the end, just writing a loop and not seeing any thread-safety problems is not proof that it's thread-safe.
 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually the question i am asking is if all the methods accessing this static variable are also static.


these static methods and variables will be stored in class memory right?

Does it gives any advantage for thread safety. I have seen one application where this feature is used for skipping synchronization.

Anyways what was the result of your testing.
Can you test with static methods?

Seetharaman Venkatasamy wrote:
mahajan amit wrote:
Is this static variable thread safe?

No, it is not thread safe. you can see this behavior to write one java program
1.start two thread on single object
2. declare one static int in that object
3. and loop like below in your run()

you need proper synchronization for above code.

<edit>William beaten me ;)</edit>
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
mahajan amit wrote:Actually the question i am asking is if all the methods accessing this static variable are also static.


Doesn't matter. The rules for access to shared variables are always the same. If a shared resource can be accessed by multiple threads concurrently, and if one or more of those threads is modifying the resource, then you have to provide exclusive access to that resource (via synchronization or the higher-level tools in java.util.concurrent.*, or, in some cases, simply making a variable volatile).

these static methods and variables will be stored in class memory right?


All member variables--both static and non-static--are store on the heap, and could potentially be shared.

All method executable code is stored in the "method area", which, according to the JVM spec, is "logically part of the heap." This is irrelevant though, since methods' executable code's location has nothing to do with thread safety. Thread safety is about access to shared, modifiable resources, and code isn't modified.

Does it gives any advantage for thread safety.


No. None at all. Zero.

I have seen one application where this feature is used for skipping synchronization.


Either you misunderstood what you saw, or the author of that code misunderstood the fundamentals of thread safety.

Anyways what was the result of your testing.
Can you test with static methods?


Testing can never prove that something is thread-safe. In the right situations, and if you know what you're doing, you can devise a test that makes it very likely that your code is thread-safe if it passes, but it's basically impossible to be 100% sure.

If you're lucky, your test will show when your code is not thread-safe, but it's possible to run millions of cycles of tests with no problem, and then have thread-safety break down when you get to production, just because of slightly different hardware or different load on the machine or a different JVM version or OS patch level giving different scheduling rules.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A bit picky ... but static variables have a albeit small advantage around initialization ..

if a field is set in a static initializer, it is guaranteed to be made visible, correctly, to any thread that accesses that class.


.. over a non static , so I wouldn't say no difference just not a lot.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris Hurst wrote:A bit picky ... but static variables have a albeit small advantage around initialization ..

if a field is set in a static initializer, it is guaranteed to be made visible, correctly, to any thread that accesses that class.


.. over a non static , so I wouldn't say no difference just not a lot.


I stand corrected.
 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Static Method + Data -> Stack

Objects -> Heap

Thread 1 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack

Thread 2 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack

Thread 3 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack

In case all methods are also static they will always be copied to heap and get new memory.


Does it makes my Question clearer?

Any program some one can write to deny it?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
mahajan amit wrote:Static Method + Data -> Stack


No. All executable code and all class definitions and all objects and all member variables (including statics) are on the heap.

The only thing that's on the stack is local variables. Note that a variable in Java holds either a primitive or a reference, but never an object. So what's on the stack is only local variables holding primitive values and local variables holding null or holding reference values that point to objects that are on the heap.

Objects -> Heap

Thread 1 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack

Thread 2 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack

Thread 3 -> Read static -> copy stack static value to Heap
-> perform Read Write

-> Save changes to stack



I have no idea what you're trying to say here, but it suggests you have some confusion about how threads, variables, and the stack work.

In case all methods are also static they will always be copied to heap and get new memory.


No. All methods' executable code--the bytecode that resulted when you compiled your .java file--lives on the heap, always. And it's never copied. There's no need to, since it's read-only.

Additionally, all member variables, including static member variables, live on the heap, as do all the objects they point to.

The only things that are copied to the stack are parameters when you call a method, but again, those are primitives or references, not objects.

Does it makes my Question clearer?


Not really, no.

Any program some one can write to deny it?


Deny what? If you want to show whether something lives on the heap or the stack, you don't do that with code, you do that by citing the JLS and/or JVM spec. And if you want to prove whether something is thread-safe or not using code, then as I believe I already indicated, it's impossible to prove that it is thread-safe, and in general very difficult to prove that it is not.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
mahajan amit wrote:Static Method + Data -> Stack

...
The only thing that's on the stack is local variables--primitives and references.


And in that case, there is no difference between static methods or instance methods. For example, if you had a class full of static methods, and all the static methods only used method-local data, then yes your methods would be thread safe without any further synchronization or protection. But if you had used instance methods which used only method local data it too would be thread safe without further synchronization. So no difference there.
 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jeff and Steve, i got some clarity, but i will definitely write one program to check if i can corrupt one variable by many threads.

Something that will do 2 + 2 and may result 5

Thanks a lot...
 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Million dollar proof that i was wrong





output is strangely not 2
a: 902+b: 910is 1812
a: 903+b: 911is 1814
a: 904+b: 912is 1816
a: 895+b: 903is 1798
a: 898+b: 906is 1804
a: 900+b: 908is 1808
a: 903+b: 911is 1814

i was (900 times ) wrong about static
 
mahajan amit
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And here is the solution
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
The only thing that's on the stack is local variables. Note that a variable in Java holds either a primitive or a reference, but never an object. So what's on the stack is only local variables holding primitive values and local variables holding null or holding reference values that point to objects that are on the heap.


I don't mean to add to the confusion, but the HotSpot server VM has been able to perform escape analysis since Java 6u14, which could result in stack allocation of objects - or scalar replacement, but this was about objects on the stack - if I remember correctly.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jelle Klap wrote:
Jeff Verdegan wrote:
The only thing that's on the stack is local variables. Note that a variable in Java holds either a primitive or a reference, but never an object. So what's on the stack is only local variables holding primitive values and local variables holding null or holding reference values that point to objects that are on the heap.


I don't mean to add to the confusion, but the HotSpot server VM has been able to perform escape analysis since Java 6u14, which could result in stack allocation of objects - or scalar replacement, but this was about objects on the stack - if I remember correctly.


Thanks for the correction.

I didn't think that it was in 6. I thought it was talked about for 7, but I never found out if that actually made it into the spec, and if so, if Oracle's JVM actually made use of it. Usually in these discussions I'll mention it as an aside, but I just got lazy this time.
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:I didn't think that it was in 6. I thought it was talked about for 7, but I never found out if that actually made it into the spec, and if so, if Oracle's JVM actually made use of it.


Yeah, that's where I get a little hazy on the details as well. The release notes for Java 6u14 mentions escape analysis it in the Java HotSpot VM 14.0 section:

Optimization Using Escape Analysis
The -XX:+DoEscapeAnalysis option directs HotSpot to look for objects that are created and referenced by a single thread within the scope of a method compilation. Allocation is omitted for such non-escaping objects, and their fields are treated as local variables, often residing in machine registers. Synchronization on non-escaping objects is also elided.

That seems to only pertain to scalar replacement, and not stack allocation of objects.

Edit:
The Java 7 release notes also refer to HotSpot JVM performance enhancements that includes a section on escape analysis, but that explicitly states:

After escape analysis, the server compiler eliminates scalar replaceable object allocations and associated locks from generated code. The server compiler also eliminates locks for all non-globally escaping objects. It does not replace a heap allocation with a stack allocation for non-globally escaping objects.

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic