• Post Reply Bookmark Topic Watch Topic
  • New Topic

Race Condition for Threads to increment a variable

 
Abhijit Choudhury
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok another silly doubt from me
There is a global variable (static) say X initialized to zero

Now my Main Thread spins like 1000 threads or more and each of them is trying to increment that variable

Now here is my doubt
Do I really need a synchronized block like
synchronized(this)
{
X++; // Its just one step increment
}
to make the application thread safe because as far as I understand synchronized block is used so that a the thread executes a sequence of steps or statements and during its execution through those steps no other thread should interfere.

I believe X++; should also work fine because there is just one step which does not need any sequencing meaning no synchronization.
 
Henry Wong
author
Sheriff
Posts: 22518
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe X++; should also work fine because there is just one step which does not need any sequencing meaning no synchronization.


Unfortunately, this is not true. There is no increment opcode, in the Java bytecode instruction set. The JIT may compile it to one, but there is no guarantee that this will be enforced by the specification.

To do what you want... take a look at the atomic variables.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html

These variables provide simple (which can be built upon) access to variables, in a fashion that doesn't need any synchronization.

Henry
 
Abhijit Choudhury
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Henry Wong:


Unfortunately, this is not true. There is no increment opcode, in the Java bytecode instruction set. The JIT may compile it to one, but there is no guarantee that this will be enforced by the specification.

To do what you want... take a look at the atomic variables.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html

These variables provide simple (which can be built upon) access to variables, in a fashion that doesn't need any synchronization.

Henry


Thnx Henry but these atomic variables you talking about may internally use sync blocks.

And Ok I understand that there is no opcode for ++ or -- but what I am trying to achieve is the threads I talked about can they make simultaneous changes to the variable. Or can i use a local variable instead of static so that multiple threads cant access it at same time while incrementing
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Abhijit]: Thnx Henry but these atomic variables you talking about may internally use sync blocks.

Except that they don't. You can investigate the source code yourself if you like.

[Abhijit]: And Ok I understand that there is no opcode for ++ or -- but what I am trying to achieve is the threads I talked about can they make simultaneous changes to the variable.

Certainly it's possible for threads to make simultaneous changes to the variable. But if you reject known thread-safe techniques like using synchronization or using atomic variables, there's a good chance that your simultaneous changes can result in invalid data or nonsensical results.

[Abhijit]: Or can i use a local variable instead of static so that multiple threads cant access it at same time while incrementing

If you use a local variable, different threads will not share data at all; each will see its own copy. Perhaps you meant instance variable. If you do that, and protect it with synchronization, then different threads may be able to execute concurrently, if they are operating on different instances. Generally the decision to use static or instance variables depends on the nature of the data itself - what does it represent? Some things are naturally static, and some are not. Synchronization should not be your driving concern here.

In your original code

if X is static, then it makes no sense at all to try to protect it with a "synchronized (this)" - "this" implies an instance, which may or may not exist. And two different threads should not be allowed to execute this method simultaneously just because they are using different instances - because X has nothing to do with those instances; it's a static variable. Instead, to protect access to a static variable, you should typically synchronize on the Class instance for the current class. This is an object shared by the entire class. It's also possible to sync on some other shared object, but using the Class object is the most common choice - and that's what static synchronized methods do.

Or as Henry suggests, it's certainly possible to use atomic variables. But if you use synchronzation, be sure to sync on an appropriate object.
[ December 25, 2007: Message edited by: Jim Yingst ]
 
Henry Wong
author
Sheriff
Posts: 22518
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

[Abhijit]: Thnx Henry but these atomic variables you talking about may internally use sync blocks.

[Jim]: Except that they don't. You can investigate the source code yourself if you like.


Abhijit, first, thanks for fixing your screen name.

Basically, here is how the atomic variables works. The Compare and Set method is a native method (JNI). The implementation of this method is to use the CAS opcode -- the native processor instruction which guaratees that the conditional set is done atomically. Interestingly, this instruction is available, in one form or another, in all modern processors.

All the other methods are implemented in Java. Basically, using the Compare and Set method, as the basis for the (optimistic) implementation.

Henry
[ December 25, 2007: Message edited by: Henry Wong ]
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
On the first look at the AtomicXXX classes, one would often wonder why would i need such classes when all that i am doing is x++ sort of an operation. Looking at the javadocs also suggests that use it when you need something like a compareAndSet sort of a functionality, but these classes are definetly useful for innocent variable updations like the one you have mentioned.
The point is that x++ converts to:
x= x + 1;

This means that increment 1 to the "current" value of x and assign it back to x. As Henry mentioned, these two steps are not a single op code and thus the thread processing this instruction can be scheduled out after processing the first instruction i.e x + 1; when the thread is scheduled back then the value of x could have changed, but, this thread unaware of the change will overwrite the previous one with its value. So, you will essentially have dirty data.
(In the above scenario, even if the thread is not scheduled out, other thread(multi-processor systems) can change the value of x between the two op code processing)
With AtomicXXX classes, you can use a getAndIncrement() type of methods to atomically do a x++ operation.

Hope this helps.
 
Abhijit Choudhury
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot Henry and Jim I ll continue to ask you guyz my doubts as and when i get them
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Abhijit Choudhury:
Thanks a lot Henry and Jim

You did not say thanks to me .. I took so much of time to write that information !!!
Just kiddin
We are always pleased to help!!!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!