This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.

Hello guys!!!
I have got a problem in program codes (from the book, Head First Java 2nd ed., 'Java 5.0'). The output isn't given in the book. I have Java 7 installed (jdk1.7.0_05).
The programs are compile and run, but the second or third program is not giving the output it appears it should give.. Can you spot the problem in the codes I am giving below? And how to fix it? I could not find the 'synchronized' keyword in the Java 5.0 API. Can you tell where it can be located?

Problem: I don't know why the problem is occuring, and the three programs are giving the similar output even when the method 'increment()' is synchronized. Of the codes below, the first two programs are same as given in the book, the third is that I have modified using the second one.

There are three programs here: 1. TestSyncTest.java
2. Tst2.java
3. Tst3.java
The post is long due to the programs' outputs, but the output is simple.

Program 1: TestSyncTest.java

It gives the output as: (see the 'bold' and the 'dark red' colored text)
-----------------------
balance is 1
balance is 3
balance is 2 balance is 4
balance is 5
balance is 6
balance is 7
balance is 8
balance is 9
balance is 10
balance is 11
balance is 13
balance is 14
balance is 15
balance is 16
balance is 17
balance is 18
balance is 19
balance is 20
balance is 21
balance is 22
balance is 23
balance is 24
balance is 25
balance is 26
balance is 27
balance is 28
balance is 29
balance is 30
balance is 31
balance is 32
balance is 33
balance is 34
balance is 35
balance is 36
balance is 37
balance is 38
balance is 39
balance is 40
balance is 41
balance is 42
balance is 43
balance is 44
balance is 45
balance is 46
balance is 47
balance is 12 balance is 49
balance is 50
balance is 51
balance is 52
balance is 53
balance is 54
balance is 55
balance is 56
balance is 57
balance is 58
balance is 59
balance is 60
balance is 61
balance is 62
balance is 63
balance is 64
balance is 65
balance is 66
balance is 67
balance is 68
balance is 69
balance is 70
balance is 71
balance is 72
balance is 73
balance is 74
balance is 75
balance is 76
balance is 77
balance is 78
balance is 79
balance is 80
balance is 81
balance is 82
balance is 83
balance is 84
balance is 85
balance is 86
balance is 87
balance is 88
balance is 89
balance is 90
balance is 91
balance is 48 balance is 92
balance is 93
balance is 94
balance is 95
balance is 96
balance is 97
balance is 98
balance is 99
balance is 100
------------------------
Bold text indicates- the last 'balance' update is lost. Dark red color indicates- a +2 increment, that should not happen, because we are doing +1 to the balance.
It should not happen that after balance 3, the balance is 2, but as here the increment method is not 'synchronized', it may happen. Now, see the second and third programs (and their output) where the method 'increment()' is synchronized.

Program 2: Tst2.java

Program 2's output is:
---------------------------
balance is 1
balance is 2
balance is 3
balance is 4
balance is 5
balance is 6
balance is 7
balance is 8
balance is 9
balance is 10
balance is 11
balance is 12
balance is 13
balance is 14
balance is 15
balance is 17
balance is 18
balance is 16 balance is 19
balance is 20
balance is 21
balance is 22
balance is 23
balance is 24
balance is 25
balance is 26
balance is 27
balance is 28
balance is 29
balance is 30
balance is 32
balance is 33
balance is 31 balance is 34
balance is 35
balance is 36
balance is 37
balance is 38
balance is 39
balance is 40
balance is 41
balance is 43
balance is 42 balance is 44
balance is 45
balance is 46
balance is 47
balance is 48
balance is 49
balance is 50
balance is 51
balance is 52
balance is 53
balance is 54
balance is 55
balance is 56
balance is 57
balance is 58
balance is 59
balance is 60
balance is 61
balance is 62
balance is 64
balance is 65
balance is 66
balance is 67
balance is 63 balance is 68
balance is 69
balance is 70
balance is 71
balance is 72
balance is 73
balance is 74
balance is 75
balance is 76
balance is 77
balance is 78
balance is 79
balance is 80
balance is 81
balance is 82
balance is 83
balance is 84
balance is 85
balance is 86
balance is 87
balance is 88
balance is 89
balance is 91
balance is 92
balance is 93
balance is 94
balance is 95
balance is 96
balance is 97
balance is 98
balance is 90 balance is 99
balance is 100
---------------------------
Silmilar probelem here too..

I did then modify this second program thinking that the 'balance' variable here must be acting here as 'local' to each of the two threads. The modified program is below.
Program 3: Tst3.java

It's output is:
----------------------------------
balance is 1
balance is 2
balance is 3
balance is 4
balance is 5
balance is 6
balance is 7
balance is 8
balance is 9
balance is 10
balance is 11
balance is 12
balance is 13
balance is 14
balance is 15
balance is 17
balance is 18
balance is 16 balance is 19
balance is 20
balance is 21
balance is 22
balance is 23
balance is 24
balance is 25
balance is 26
balance is 27
balance is 28
balance is 29
balance is 30
balance is 32
balance is 31 balance is 33
balance is 34
balance is 36
balance is 37
balance is 38
balance is 35 balance is 39
balance is 40
balance is 41
balance is 42
balance is 43
balance is 44
balance is 45
balance is 46
balance is 47
balance is 48
balance is 49
balance is 50
balance is 51
balance is 52
balance is 53
balance is 54
balance is 55
balance is 56
balance is 57
balance is 58
balance is 59
balance is 60
balance is 61
balance is 62
balance is 63
balance is 65
balance is 66
balance is 67
balance is 68
balance is 69
balance is 70
balance is 71
balance is 64 balance is 72
balance is 73
balance is 74
balance is 75
balance is 77
balance is 78
balance is 79
balance is 80
balance is 76 balance is 81
balance is 82
balance is 83
balance is 84
balance is 85
balance is 86
balance is 87
balance is 88
balance is 89
balance is 91
balance is 92
balance is 93
balance is 94
balance is 95
balance is 96
balance is 97
balance is 98
balance is 99
balance is 90 balance is 100
----------------------------------
Here also that problem is occuring... So, why does not the balance increase continuously, which I think it should, without giving a lesser value at some times?
.... whoofffffffffff (a sigh..).............................................. Thanks folks.

Note: I have put all the three programs in different folders and then run each one of them seperately.

I think the author should not have used an inner class in this case as it clouds the example the code is meant to demonstrate (I have not read this in context mind) ...

is the right answer though in this case if you have an inner class it becomes confusing as the inner class adds the complication of the inner's this and its relation to the outer classes this. Your synchronized is syncing on TestSync.this of which you have two (a&b) rather than Tst3.this of which you have one (p1). You basically have to synchronize on a common object for the synchronized to do its magic.

The simplest solution (to explain, you can do it in one line ;-) ) is probably this (other solutions exist ;-) )...

"Eagles may soar but weasels don't get sucked into jet engines" SCJP 1.6, SCWCD 1.4, SCJD 1.5,SCBCD 5

Ashish Ramteke
Ranch Hand

Joined: Oct 24, 2012
Posts: 88

1

posted

0

Hi, Chris Hurst, thanks!! I am sorry for my very late reply.
The first time I glanced at your post, I did not understand about "TestSync.this" and "Tst3.this".. because I am not much experienced..
But, then I saw your code and run it and checked the output, but the output was still, 'similar' to the previous ones... it was not coming as I expected..
But then I looked the code again and it struck to me that perhaps in my code "Tst2.java" the method run() needs to be synchronized in order to get the continuously increasing (by +1) output. It seems that maybe when one object is in the increment() method, after finishing that method (increment()) the object may go to sleep and the other object might enter just before the print statement and print the value, then after running for sometime, this second object might go to sleep, and then the first object might enter the method (just before the print statement) and print the then (previous) value of balance.
Here, the synchronized increment method (Tst2.java) is doing its job correctly because it increments its balance as one atomic work, but the error that occurs is in the display of the balance's values only.
Thank you.

You have a second problem as you say with your system out (it updates correctly but displays a wrong result) which to fix change my code to ..

and remove the other System.out.println("balance is " + balance);

synchronizing run won't work as you have two thread objects with two this pointers so you have two locks the threads aren't locking on the same lock, run would have to be static for that to work (which it can't be for your purposes).

If it helps I use Eclipse to debug these things I set break points in the suspect code and suspend individual threads only, provide you pick the right suspect code the bug should be easily reproducible on every loop.