• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

value changed for no reason

 
Ranch Hand
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Marshal
Posts: 79239
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Those are both values of a field, not local variables?
You are sure the other code is not relevant?
 
Kevin Tysen
Ranch Hand
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are there Threads that you've created in this program?
 
Kevin Tysen
Ranch Hand
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
try using 'this' keyword for those fields as they are class variables.
 
Kevin Tysen
Ranch Hand
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 79239
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 255
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see. Thank you.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic