Deadlock analysis
1, the production of deadlocks
There is the following code, which simulates the transfer between two accounts
void Transfer (account From,account To,int money) { from.setamount (From.getamount ()-money); To.setamount (To.getamount () +money);}
Single-threaded, this code is sure to be okay, but there are problems with multithreading
Now lock it, lock the code as follows
void Transfer (account From,account To,int money) { synchronized (from) { synchronized (to) { From.setamount (From.getamount ()-money); To.setamount (To.getamount () +money);}}
Synchronized, an object lock, the first synchronized locks the from object, and the second synchronized locks the to object.
In multithreaded situations, only one thread in multiple threads at the same time can get the object lock and manipulate the code snippet inside the object lock.
But after you add the object lock, there may be a deadlock!
Transfer (A,B,100) and Transfer (B,A,100) at the same time, that is, A to B transfer, B is also a transfer to a
"1" A to B transfer, thread x get a This object lock
"2" B to a transfer, thread y get b This object lock
Operation "1" urgently requires the B object lock, in order to transfer operations
Operation "2" urgently requires a This object lock, in order to transfer operations
Two threads are waiting for other threads in the group to release the lock, and a deadlock occurs!
2. Deadlock resolution
From those aspects?
"1" break mutually exclusive wait
Generally speaking, we must lock the object for the safety of the program, so this condition cannot be broken.
"2" Break hold and wait, i.e. occupy wait
All resources can be obtained at once, and the sample code is not a one-time acquisition of both the From and to resources, but the distribution gets.
Method One: Give to add a very short time-out, once trying to get to timeout, immediately release a start held from the lock, after some time
Try again to get the from and to locks. is the recommended method
Method Two: Add a global lock to this code, you can guarantee from and to at the same time, after the transfer operation is complete, release the global lock. is more secure, but the bank has a large number of accounts, transfer operations are very frequent, the use of this method is bound to cause a serious decline in performance
"3" Break the Loop wait
In order to obtain resources, according to the account ID of the size of the operation, the ID of the smaller accounts first transfer operations, the ID is larger than the account after the
Transfer operation. But in real life, some things do not have the ID, that is, there is no order, this time need to be forced to add order.
"4" To get rid of the deprivation of waiting
Join timeout, the last resort method, the user's transfer operation failed, the user experience is not good
The solution of personal recommendation:
At the expense of a user's brief wait time, use Method 1 in "2"
Related articles:
The concept and solution of deadlock in Java
The concept of deadlock and the condition of deadlock