wood burning stoves*
The moose likes Beginning Java and the fly likes value changed for no reason Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "value changed for no reason" Watch "value changed for no reason" New topic
Author

value changed for no reason

Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
An instance value keeps changing for no apparent reason. I added System.out.println() commands to see where it changes.



When I run the program, I get

3: firstProbIndex is 1 and lastProbIndex is 1
4: firstProbIndex is 1 and lastProbIndex is 0

Somehow lastProbIndex changes by calling updateSAMenu()
I have no idea why.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38045
    
  22
Those are both values of a field, not local variables?
You are sure the other code is not relevant?
Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
They are both field variables of the same class. And the two methods are also in that same class.
If they were local (inside method) variables, it would not compile.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Are there Threads that you've created in this program?


[Jess in Action][AskingGoodQuestions]
Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
I have no Threads explicitly in this program, but I've heard that when there is a GUI,
the JVM automatically sets up Threads.

There is a text field on the GUI that calls the methods I've listed. The actionEvent
method looks like this:

if (checkAndRecord()){
moveIt();
}

checkAndRecord() alters the value of lastProbIndex, but not firstProbIndex, and
returns a boolean.

moveIt() changes the value of firstProbIndex, and then calls setFinalIndex().

setFinalIndex changes the value of lastProbIndex to 1, as expected. But according to the
command line output, the value is 1, but then when the program starts setFinalIndex(),
the value is 0.

The most fishy thing I see here is the checkAndRecord() method, which might change the
value of lastProbIndex to 0 if it does not finish running before moveIt() is called.
But is it possible for the program to start moveIt() before checkAndRecord() finishes?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

You may have stumbled upon the landmine of unsynchronized access to variables from multiple threads.

Try an experiment: add "volatile" to the declaration of the member lastProbIndex. Does this change the behavior?
Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
I added the word "volatile" to the declaration as you suggested. It looks like this:



I compiled and ran it again and got the exact same results. The value of lastProbIndex changed somehow.
kannan vinayagam Duraiswamy
Ranch Hand

Joined: Jan 12, 2009
Posts: 52
try using 'this' keyword for those fields as they are class variables.


Kannan.DV
Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
I finally figured out what the problem was with this program.
When I was looking at the code carefully one more time I stumbled upon this line:



This was a line inside of my method. So when the System.out.println() commands inside
this method were referencing lastProbIndex, they were referencing the local variable,
and the System.out.println() commands elsewhere in the program were referencing the
class variable. And the class variable lastProbIndex was not really being set to equal
firstProbIndex.

I did not know that the compiler would let you get away with having a local variable and
a class variable have the same name.

By the way, what does 'volatile' mean? You don't have to explain if you could just direct
me to some web page that explains it.

Thank you everyone for your help!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38045
    
  22
Yes, the compiler will allow local variables and fields with the same names. Just think, in some languages (I think C++ is one) you can have local variables in inside blocks with the same name as local variables in outside blocks.
You are probably experienced enough to use an IDE; most of them will warn you if you try using local variables and fields with the same names.

When you have a value, it starts off life in your RAM, then it is moved to the cache on your CPU for processing. Then it is moved into a register, then it is processed, and moved back via the cache to the RAM. So you can have three copies of the variable, and they might not be the same value, or even more than three copies if you have multi-level cache, as most recent chips do.
When the JVM requires the value of that variable, it picks whichever value it thinks most appropriate. In a single-threaded application, the JVM "knows" the history of the values and can find the most recent.
But in a multi-threaded application a thread will start with the copy in RAM, because it doesn't "know" there are any other copies. This might however be an out of date value.

If you label a field volatile, that insists the JVM update the copy in RAM immediately, so other threads find an up to date value there.

At least I think that's how volatile works.
Kevin Tysen
Ranch Hand

Joined: Oct 12, 2005
Posts: 255
I see. Thank you.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: value changed for no reason
 
Similar Threads
increment operators
Doubt in Inquisition question
variables & values
Dan Chisolm question on operator precedence
Cave In