Java Reference
In-Depth Information
When the updateBalance() method is invoked, the CPU has to execute six instructions to add 10 to and subtract
10 from the balance variable. When the balance update thread is in the middle of executing any of the first three
instructions, the balance monitor thread will read the balance value as 100. When the balance update thread has
finished executing the third instruction, the balance monitor thread will read its value as 110 . The value 110 for the
balance variable will be restored to 100 only when the balance update thread executes the sixth instruction. Note
that if the balance monitor thread reads the value of the balance variable any time after the execution of the third
instruction and before the execution of the sixth instruction by the balance update thread, it will read a value that is
not the same as the value that existed at the start of the updateBalance() method execution. Table 6-1 shows how the
value of the balance variable will be modified and read by the two threads.
Table 6-1. Instruction Executions for Multiple Threads
Statement (Suppose Balance
Value is 100 to Start With)
Instructions Being Executed by
the Balance Update Thread
The Value of Balance Read by
the Balance Monitor Thread
balance = balance + 10;
register-1 = balance;
100
register-1 = register-1 + 10;
100
balance = register-1;
Before execution: 100
After execution: 110
balance = balance - 10;
register-2 = balance;
110
register-2 = register-2 - 10;
110
balance = register-2;
Before execution: 110
After execution: 100
In your program, the monitor thread was able to read the value of the balance variable as 110 because you
allowed two threads to modify and read the value of the balance variable concurrently. If you allowed only one thread
at a time to work with (modify or read) the balance variable, the balance monitor thread would never read the value
of the balance variable other than 100 .
The situation where multiple threads manipulate and access a shared data concurrently and the outcome
depends on the order in which the execution of threads take place is known as a race condition . A race condition in
a program may lead to unpredictable results. Listing 6-4 is an example of a race condition where the program output
depends on the sequence of execution of the two threads.
To avoid a race condition in a program, you need to make sure that only one of the racing threads works with the
shared data at a time. To solve this problem, you need to synchronize the access to the two methods updateBalance()
and monitorBalance() of the BalanceUpdate class. That is, only one thread should access one of these two methods
at a time. In other words, if one thread is executing the updateBalance() method, another thread that wants to
execute the monitorBalance() method must wait until the thread executing the updateBalance() method is
finished. Similarly, if one thread is executing the monitorBalance() method, another thread that wants to execute
the updateBalance() method must wait until the thread executing the monitorBalance() method is finished. This
will ensure that when a thread is in the process of updating the balance variable, no other threads will read the
inconsistent value of the balance variable and vice versa.
This kind of problem that needs synchronizing the access of multiple threads to a section of code in a Java
program can be solved using the synchronized keyword. To understand the use of the synchronized keyword, I need
to discuss the Java Memory Model in brief, and the lock and wait sets of an object.
 
Search WWH ::




Custom Search