Atomic operation and volatile variables

S

Sumukh

Hi ,
I have one volatile variable declared as

private volatile long _volatileKey=0;

This variable is being incremented(++_volatileKey) by a method which is
not synchronized. Could there be a problem if more than one thread tries
to change the variable ?
In short is ++ operation atomic in case of volatile variables ?

Thanks

Sumukh
 
S

Skip

Sumukh said:
Hi ,
I have one volatile variable declared as

private volatile long _volatileKey=0;

This variable is being incremented(++_volatileKey) by a method which is
not synchronized. Could there be a problem if more than one thread tries
to change the variable ?
In short is ++ operation atomic in case of volatile variables ?

It's not atomic on my system, so it's not optimized away by the VM.

My test was like this:


private volatile int inc = 0;
private final int loops = 1024 * 1024 * 8;

public void run(){
for (int i = 0; i < loops; i++)
value++;
}

// later in the app
System.out.println("expected: " + (loops * threads));
System.out.println("value: " + value);

When I run this app several times, inc always has another value.
expected: 134217728
current: 78678507
So rougly half of the incs got mangled when running 16 threads.

HTH
 
T

Thomas G. Marshall

Skip coughed up:
It's not atomic on my system, so it's not optimized away by the VM.

My test was like this:


private volatile int inc = 0;
private final int loops = 1024 * 1024 * 8;

public void run(){
for (int i = 0; i < loops; i++)
value++;
}

// later in the app
System.out.println("expected: " + (loops * threads));
System.out.println("value: " + value);

When I run this app several times, inc always has another value.
expected: 134217728
current: 78678507
So rougly half of the incs got mangled when running 16 threads.

Interesting test. I've performed almost identical tests before myself, but
for differing objectives: teaching synchronization fundamentals.

Can you supply the /entire/ set of sources? I've got a morbid curiosity to
see if there is a mistake in there (I strongly doubt it, don't get me wrong,
but want to see what your test was /precisely/ "just in case"----please take
no offense, and feel free to ignore me with certainly no grumbling on my
part whatsoever ) . Thanks!
 
C

Chris Uppal

Sumukh said:
In short is ++ operation atomic in case of volatile variables ?

No. Not by definition; though I suppose it might happen to be "atomic" on some
particular combinations of machine architecture and code-generation strategy.

-- chris
 
T

Thomas G. Marshall

Thomas Hawtin coughed up:
No.

If you are using 1.4 or earlier, you need to switch the volatile to
synchronisation, at least for *all* updates (including the first).
From 5.0 use this:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.html

Tom Hawtin


Yep. Or you can create something that is an extension of Number in the
first place:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/AtomicInteger.html

If that is more appropos to your situation. Tom's Hawtin's suggestion is
the most likely to be useful though IMO.
 
S

Skip

Thomas G. Marshall said:
Skip coughed up:

Interesting test. I've performed almost identical tests before myself, but
for differing objectives: teaching synchronization fundamentals.

Can you supply the /entire/ set of sources? I've got a morbid curiosity to
see if there is a mistake in there (I strongly doubt it, don't get me wrong,
but want to see what your test was /precisely/ "just in case"----please take
no offense, and feel free to ignore me with certainly no grumbling on my
part whatsoever ) . Thanks!

Well, I'm using quite a bit of classes to reduce the typing. It basicly
waits until all 16 threads are running, only then feeding them the same
Runnable at the same time, so have as much collisions as possible.. Without
a doubt the classes have dependecies to other classes etc etc etc. Basily
the code just does what's visible in the code that I already supplied, just
in a fancy shell. I'd hate to dump all sources on usenet, not only because
it's messy, but also because it contains lots of stuff that's not meant to
be public, yet.

Just try to imagine I did "new Thread(this).start()" 16 times and you have
basicly the same :eek:)
 
R

Roedy Green

No. Not by definition; though I suppose it might happen to be "atomic" on some
particular combinations of machine architecture and code-generation strategy.

Consider this snippet of code:
public class VolatileTest
{
private static volatile long key=0;

public static void main ( String[] args )
{
key++;
}
}

if you compile it and disassemble it with javap -c VolatileTest
you will see the ++ increment is implemented with four JVM
instructions:


getstatic #2; //Field key:J
lconst_1
ladd
putstatic #2; //Field key:J


That means it is most certainly not atomic.

However, on an Intel machine an optimising compiler or AOT compiler
might coalesce that like this:

inc key[ebx]

which would be atomic at least on a single CPU machine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top