One solution to solve the deadlock problem is to ensure a locking order, for example, add lock to A before B if A's id is less than B's.
tkli
@rootB That is an interesting idea but introduces more complexity to the programmer as mentioned. It can become very tricky to ensure code correctness over larger codebases. This seems like very good motivation for transactional memory.
dasteere
I wonder if it would be possible at the compiler level to "order" locks so that whenever multiple locks are being attained in one block it would automatically try to obtain them in order, regardless of the order the programmer wrote. This would reduce the amount of deadlocks programmers would run into.
williamx
In this case in particular, it seems like another possibility is to simply separate the synchronizations as follows: synchronize(A) { withdraw(A, amount); } synchronize(B) {deposit(B, amount); } .
kayvonf
@williamX. There's actually a problem with the approach you propose. Can you see what it is?
williamx
Oh right, it might be possible that the thread could fail when the code is trying to deposit. We would want to undo both the withdraw and the deposit.
Master
@williamx. You broke the isolation property. The write of A could be observed by others before the transaction committed, and the invariant of total amount of money in the band accounts was broken.
One solution to solve the deadlock problem is to ensure a locking order, for example, add lock to A before B if A's id is less than B's.
@rootB That is an interesting idea but introduces more complexity to the programmer as mentioned. It can become very tricky to ensure code correctness over larger codebases. This seems like very good motivation for transactional memory.
I wonder if it would be possible at the compiler level to "order" locks so that whenever multiple locks are being attained in one block it would automatically try to obtain them in order, regardless of the order the programmer wrote. This would reduce the amount of deadlocks programmers would run into.
In this case in particular, it seems like another possibility is to simply separate the synchronizations as follows: synchronize(A) { withdraw(A, amount); } synchronize(B) {deposit(B, amount); } .
@williamX. There's actually a problem with the approach you propose. Can you see what it is?
Oh right, it might be possible that the thread could fail when the code is trying to deposit. We would want to undo both the withdraw and the deposit.
@williamx. You broke the isolation property. The write of A could be observed by others before the transaction committed, and the invariant of total amount of money in the band accounts was broken.