Avoid Deadlock example

前端 未结 6 2107
谎友^
谎友^ 2020-12-13 04:51

I am wondering what are the alternative ways to avoid deadlock in the following example. The following example is a typical bank account transferring deadlock problem. What

6条回答
  •  眼角桃花
    2020-12-13 05:29

    There are three requirements you must satisfy:

    1. Consistently reduce the contents of one account by the specified amount.
    2. Consistently increase the contents of the other account by the specified amount.
    3. If one of the above is successful, the other must also be successful.

    You can achieve 1. and 2. by using Atomics, but you will have to use something other that double as there is no AtomicDouble. AtomicLong would probably be your best bet.

    So you're left with your third requirement - if one succeeds the other must succeed. There is a simple technique that works superbly with atomics and that is using the getAndAdd methods.

    class Account {
      AtomicLong balance = new AtomicLong ();
    }
    
    ...
    Long oldDebtor = null;
    Long oldCreditor = null;
    try {
      // Increase one.
      oldDebtor = debtor.balance.getAndAdd(value);
      // Decrease the other.
      oldCreditor = creditor.balance.gtAndAdd(-value);
    } catch (Exception e) {
      // Most likely (but still incredibly unlikely) InterruptedException but theoretically anything.
      // Roll back
      if ( oldDebtor != null ) {
        debtor.getAndAdd(-value);
      }
      if ( oldCreditor != null ) {
        creditor.getAndAdd(value);
      }
      // Re-throw after cleanup.
      throw (e);
    }
    

提交回复
热议问题