Java Reference
In-Depth Information
You can see from the third and fourth lines here that a credit for account 1 starts before the preceding
debit for account 2 is complete, so the operations are overlapped. If you want to force overlapping
debits and credits on the same account, you can comment out the calculation of the value for select
for the debit operation in the for loop in main() . This modification is shown shaded:
// Generate a random account index for debit operation
// select = rand.nextInt(accounts.length);
totalDebits[select] += amount; // Keep total debit tally
This will make the debit transaction apply to the same account as the previous credit, so the transactions
will always be contending for the same account.
Of course, this is not the only way of getting the operations to overlap. Another approach would be to
equip accounts with methods to handle their own credit and debit transactions, and declare these as
synchronized methods.
While testing that you have synchronization right is relatively easy in our example, in general it is
extremely difficult to be sure you have tested a program that uses threads adequately. Getting the design
right first is essential, and there is no substitute for careful design in programs that have multiple threads
(or indeed any real time program that has interrupt handlers). You can never be sure that a real world
program is 100% correct, only that it works correctly most of the time!
Deadlocks
Since you can synchronize code blocks for a particular object virtually anywhere in your program,
there's potential for a particularly nasty kind of bug called a deadlock . This involves a mutual
interdependence between two threads. One way this arises is when one thread executes some code
synchronized on a given object, theObject say, and then needs to execute another method that
contains code synchronized on another object, theOtherObject say. Before this occurs though, a
second thread executes some code synchronized to theOtherObject , and needs to execute a method
containing code synchronized to the first object, theObject . This situation is illustrated here:
This gives
a chance to start
thread1
thread2
thread2
run(){
synchronized(theObject){
sleep(1000);
theOtherObject.method2()
run(){
synchronized(theOtherObject){
sleep(1000);
theObject.method1()
2
thread1 gets
control back
4
}
}
1
}
}
3
5
6
theObject
theOtherObject
thread1
theObject
thread2
theOtherObject
has control
has control
method1()
method2()
of
of
can't
thread2
thread1
theObject
continue until
releases
can't
thread1
thread2
theOtherObject
thread2
continue until
releases
so
gets control back
Search WWH ::




Custom Search