Activity 8.4 - Running the GoodThread and the BadThread

Topic

This activity demonstrates the effect of the Java synchronized keyword.

Materials

In addition to the Solution document, the project for this activity contains the following classes:

Task

Your task will be to study the classes we have provided, and to alter one of the methods so that the program behaves correctly and the bank account is not left in an inconsistent state.

Here is an explanation of the classes:

Instructions

Build and run the program, setting ex8_4.Main as the main class.

You should see that methodA and methodB can access the shared data concurrently. Evidence for this is that the balance is generally reported as 1. This is because one thread has incremented the balance, but before it can decrement the balance back to 0 and exit the method the other thread has got in and read the incremented value.

What is happening here is that the good thread calls the synchronized methodA and must acquire the lock associated with the BankAccount object in order to execute the method. However this is not enough to protect the data. The bad thread calls the unsynchronised methodB and so does not need to acquire the lock and can go right ahead without it.

Thus nothing stops the bad thread accessing the data before the good thread is finished with it!

Moreover, since the bad thread never acquires the lock, the good thread can always get hold of it, so it can proceed to access the data before the bad thread is through with it.

Now alter methodB so it is synchronized. When you run the program again you should find a dramatic difference. The bad thread must now also acquire the lock belonging to the BankAccount before it can go ahead. Since both threads now require the lock, only one of them can access the data at a time, and once a thread starts executing its method it will finish without interference, and only when it exits will the other thread be able to proceed. You should be able to see this from the printout.

The balance will now always be given as 0, of course, because a thread that gets to increment the balance will also get to decrement it again before the other thread can read its value.