Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > volatile

Reply
Thread Tools

volatile

 
 
Timo Nentwig
Guest
Posts: n/a
 
      03-31-2006
Hi!

I'm still not completely certain about the volatile keyword. Is it
actually required in the example below or would it only be required if
go() would access the fields of Stats directly (if they were
accessible, of course)?

Thanks
Timo

import java.util.Timer;
import java.util.TimerTask;

public class Test
{
class Stats
{
private volatile int counter = 0;
private volatile long cumulativeTime;
private volatile int min, avg, max;

public Stats( final int period )
{
reset();

final Timer timer = new Timer( true );

timer.schedule( new TimerTask()
{
public void run()
{
System.out.println( "i=" + counter + ", cumulative=" +
cumulativeTime );

synchronized( this )
{
avg = counter == 0 ? 0 : (int)(cumulativeTime / counter);
}

reset();
}
}, period, period );
}

private void reset()
{
synchronized( this )
{
counter = 0;
cumulativeTime = 0;
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
}
}

public void register( int t )
{
synchronized( this )
{
counter++;
cumulativeTime += t;

if( t < min ) min = t;
if( t > max ) max = t;
}
}

public int average()
{
return avg;
}

public int min()
{
return min;
}

public int max()
{
return max;
}
}

private static final int PERIOD = 2500;
private static final int INTERVAL = 1000;

public static void main( String[] args )
{
new Test().go();
}

private void go()
{
final Stats stats = new Stats( PERIOD );

final Timer reporter = new Timer();
reporter.schedule( new TimerTask()
{
public void run()
{
System.out.println( "avg=" + stats.average() + ", min=" +
stats.min() + ", max=" + stats.max() );
}
}, INTERVAL, INTERVAL );

while( true )
{
stats.register( (int)Math.round( Math.random() * 10000 ) );

try
{
Thread.sleep( (int)Math.round( Math.random() * 5 ) + 5 );
}
catch( InterruptedException e )
{
}
}

}
}

 
Reply With Quote
 
 
 
 
Timo Nentwig
Guest
Posts: n/a
 
      03-31-2006
Okay, it isn't requird for cumulativeTime, sure, but what about the
other fields?

 
Reply With Quote
 
 
 
 
Timo Nentwig
Guest
Posts: n/a
 
      03-31-2006
Oops, and the synchronized isn't quite correct, introduce a mutex in
Stats and replace any occurence of synchronized( this ) by mutex

Well, anyway, what about volatile?

 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      03-31-2006
"Timo Nentwig" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> Hi!
>
> I'm still not completely certain about the volatile keyword. Is it
> actually required in the example below or would it only be required if
> go() would access the fields of Stats directly (if they were
> accessible, of course)?


Can you create a smaller example? My eyes glazed over trying to look at
that much (unformatted) code.


 
Reply With Quote
 
Timo Stamm
Guest
Posts: n/a
 
      03-31-2006
Timo Nentwig schrieb:
> Okay, it isn't requird for cumulativeTime, sure, but what about the
> other fields?



If you remove the code that is unrelated to the question, it is much
easier to understand and comment on it.
 
Reply With Quote
 
Timo Stamm
Guest
Posts: n/a
 
      03-31-2006
Timo Nentwig schrieb:
> I'm still not completely certain about the volatile keyword.



From cephas.net:

| The volatile modifier requests the Java VM to always access the shared
| copy of the variable so the its most current value is always read. If
| two or more threads access a member variable, AND one or more threads
| might change that variable's value, AND ALL of the threads do not use
| synchronization (methods or blocks) to read and/or write the value,
| then that member variable must be declared volatile to ensure all
| threads see the changed value.


The entire JSE 5 source (3,772,776 lines) uses the "volatile" modifier
111 times. According to my highly scientific analysis, you should not
use the "volatile" keyword unless your code base is larger than 34,000
lines


Timo Stamm
 
Reply With Quote
 
Timo Nentwig
Guest
Posts: n/a
 
      03-31-2006

Timo Stamm wrote:
> | The volatile modifier requests the Java VM to always access the shared
> | copy of the variable so the its most current value is always read. If
> | two or more threads access a member variable, AND one or more threads
> | might change that variable's value, AND ALL of the threads do not use
> | synchronization (methods or blocks) to read and/or write the value,
> | then that member variable must be declared volatile to ensure all
> | threads see the changed value.


Yes...

Okay, some shorter pseudo-code:

thread1{
int value;

void modify(){ value++; }
void print() {System.out.println( value ); }
}

thread2{
thread1.modify();

// IMHO I don't need volatile here:
thread1.print();

// but I wouldneed it here:
System.out.println(thread1.value);
}

 
Reply With Quote
 
Timo Nentwig
Guest
Posts: n/a
 
 
Reply With Quote
 
Timo Stamm
Guest
Posts: n/a
 
      03-31-2006
Timo Nentwig schrieb:
> Timo Stamm wrote:
>> | The volatile modifier requests the Java VM to always access the shared
>> | copy of the variable so the its most current value is always read. If
>> | two or more threads access a member variable, AND one or more threads
>> | might change that variable's value, AND ALL of the threads do not use
>> | synchronization (methods or blocks) to read and/or write the value,
>> | then that member variable must be declared volatile to ensure all
>> | threads see the changed value.

>
> Yes...
>
> Okay, some shorter pseudo-code:
>
> thread1{
> int value;
>
> void modify(){ value++; }
> void print() {System.out.println( value ); }
> }
>
> thread2{
> thread1.modify();
>
> // IMHO I don't need volatile here:
> thread1.print();
>
> // but I wouldneed it here:
> System.out.println(thread1.value);
> }


I don't think you need "volatile" in this case. There are no
/concurrent/ modifications: thread2 does the modification (through
thread1.modify), and reads the value /afterwards/.


As far as I understand it, this would be a more appropriate example:

thread1 {
int value;
while (true) {
value++;
}
}

thread1 {
while (true) {
System.out.println(thread1.value);
}
}


value should be marked volatile because the JVM could keep a copy in a
register and thread2 would never know the modified value.


Timo Stamm
 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      03-31-2006

"Timo Stamm" <(E-Mail Removed)> wrote in message
news:442d5ab4$0$7760$(E-Mail Removed)-online.net...
> Timo Nentwig schrieb:
>> Timo Stamm wrote:
>>> | The volatile modifier requests the Java VM to always access the shared
>>> | copy of the variable so the its most current value is always read. If
>>> | two or more threads access a member variable, AND one or more threads
>>> | might change that variable's value, AND ALL of the threads do not use
>>> | synchronization (methods or blocks) to read and/or write the value,
>>> | then that member variable must be declared volatile to ensure all
>>> | threads see the changed value.

>>
>> Yes...
>>
>> Okay, some shorter pseudo-code:
>>
>> thread1{
>> int value;
>>
>> void modify(){ value++; }
>> void print() {System.out.println( value ); }
>> }
>>
>> thread2{
>> thread1.modify();
>>
>> // IMHO I don't need volatile here:
>> thread1.print();
>>
>> // but I wouldneed it here:
>> System.out.println(thread1.value);
>> }

>
> I don't think you need "volatile" in this case. There are no /concurrent/
> modifications: thread2 does the modification (through thread1.modify), and
> reads the value /afterwards/.
>


Without either volatile or synchronization, there's no guarantee thread 1
will see a change made in thread 2; thread 1 might hold onto its previously
cached value indefinitely.

By the way

value++

should be a red flag. If two threads can both execute it, volatile isn't
good enough, becsue you have no guarantee about how

fetch value
increment
store the result in value

get interleaved. Nothing less than

synchronize(lock)
{
value++;
}

is reliable.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0xffc Thread 0x228 DBC 0x437b94 Jet'. ERROR [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr bazzer ASP .Net 0 03-30-2006 03:16 PM
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0x8fc Thread 0x934 DBC 0x437b94 Jet'. ERROR [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr bazzer ASP .Net 1 03-24-2006 04:20 PM
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key 'Temporary (volatile) Jet DSN for process 0x8fc Thread 0x934 DBC 0x437b94 Jet'. ERROR [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr bazzer ASP .Net 0 03-24-2006 02:22 PM
Use of the Volatile keyword for a pointer to a volatile memory block ben C Programming 5 01-11-2005 05:38 PM
Re: Volatile? Knute Johnson Java 17 07-03-2003 03:31 AM



Advertisments