wood burning stoves 2.0*
The moose likes Threads and Synchronization and the fly likes Threads/Looping: How Can This Be? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Threads/Looping: How Can This Be?" Watch "Threads/Looping: How Can This Be?" New topic
Author

Threads/Looping: How Can This Be?

Jim Shaw
Greenhorn

Joined: Jan 25, 2008
Posts: 9
I'm working my way through Head First Java (2nd ed.), and got a strange result when executing the following (Ch. 15 "Code Magnets" exercise):



I executed TestThreads four times, with the following output:
one 98099
two 98099

one 97099
two 97099

one 98099
two 98099

one 98099
two 98099

The supposed correct output is:
one 98098
two 98099

I never got this result, and don't think it's particularly likely that I will on my average attempt, although it seems possible.

What bothers me is where I got:
one 97099
two 97099

It seems to me that, given I am only adding (never subtracting) to the common counter and am looping through ThreadOne 98 times before I print the result, I should NEVER get a result less than 98000 for a.getCount() in ThreadOne.

Right? Can somebody tell me what happened here?

Much obliged,

Jim Shaw
[ May 12, 2008: Message edited by: fred rosenberger ]
Jim Shaw
Greenhorn

Joined: Jan 25, 2008
Posts: 9
Oops, noticed that my leading spaces were removed. Kind of makes it hard to read the code. Don't know how to prevent that. Sorry!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37900
    
  22
Use the CODE button below the message window.
You can replace the leading spaces by clicking the pencil and paper icon, then highlight the text you wish to reformat, then the CODE button. That will insert CODE tags round the whole block of code.
Rodrigo Tomita
Ranch Hand

Joined: Apr 28, 2008
Posts: 70
Jim,

Looking at your code, I think there is no guarantee that it will give you always the same result (so I don't think there is a correct answer - probably the book would tell you that better than I can ).

Anyway, when you have several threads running on the same data, you may have the situation where one thread reads a variable and another thread changes it. Then the first one updates the variable based on the value it read (which is no longer up to date).

Hope this helps.

Rodrigo
[ May 12, 2008: Message edited by: Rodrigo Tomita ]
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11150
    
  16

Originally posted by Jim Shaw:
Oops, noticed that my leading spaces were removed. Kind of makes it hard to read the code. Don't know how to prevent that. Sorry!


I put the code tags in for you.


There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19649
    
  18

I tried this as well, and even got 94098 and 94097.

I think the reason is because numeric additions are not atomic. In fact, any addition can be viewed as the following:

// 3
Now if the other thread takes the value of counter at point 2, the addition in this thread will be nullified.

I have made the updateCounter method synchronized and I got expected results several times in a row.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Jim Shaw
Greenhorn

Joined: Jan 25, 2008
Posts: 9
Ahh, I see Rodrigo's point...

Sometimes I'm getting a defacto subtraction due to timing issues:
ThreadTwo retrieves count and it's, say, 4372.
ThreadOne updates count to 4472.
ThreadTwo updates count to 4373, and we've lost 100.

That's ugly!

Thanks Rodrigo, and thanks to all for your helpful posts!
Jim Shaw
Greenhorn

Joined: Jan 25, 2008
Posts: 9
Thanks Rob,

Yes, the answer would be to make it atomic.

Regards,

Jim Shaw
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Threads/Looping: How Can This Be?
 
Similar Threads
Why doesn't this code work in Netbeans 7.0?
TestThreads Code Magnets exercise Head First Java
Use of Private Constructor in Thread Example
The static synchronized methods of the same class always block each other as only one lock per class
wait and notify