首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免死锁示例

避免死锁示例
EN

Stack Overflow用户
提问于 2012-11-11 06:54:23
回答 4查看 11.8K关注 0票数 21

我想知道在下面的例子中避免死锁的替代方法是什么。下面的例子是一个典型的银行转账死锁问题。在实践中有哪些更好的方法来解决这个问题?

代码语言:javascript
复制
class Account {
     double balance;
     int id;
     public Account(int id, double balance){
          this.balance = balance;
          this.id = id;
     }
     void withdraw(double amount){
          balance -= amount;
     } 
     void deposit(double amount){
          balance += amount;
     }
}
class Main{
     public static void main(String [] args){
           final Account a = new Account(1,1000);
           final Account b = new Account(2,300);
           Thread a = new Thread(){
                 public void run(){
                     transfer(a,b,200);
                 }
           };
           Thread b = new Thread(){
                 public void run(){
                     transfer(b,a,300);
                 }
           };
           a.start();
           b.start();
     }
     public static void transfer(Account from, Account to, double amount){
          synchronized(from){
               synchronized(to){
                    from.withdraw(amount);
                    to.deposit(amount);
               }
          }
     }
}

我想知道如果我像下面这样在我的传输方法中分离嵌套锁,死锁问题是否会得到解决

代码语言:javascript
复制
 synchronized(from){
      from.withdraw(amount);
 }
 synchronized(to){
      to.deposit(amount);
 }
EN

Stack Overflow用户

发布于 2012-11-11 07:32:18

除了lock ordered的解决方案之外,您还可以通过在执行任何帐户转移之前在私有静态最终锁对象上进行同步来避免死锁。

代码语言:javascript
复制
 class Account{
 double balance;
 int id;
 private static final Object lock = new Object();
  ....




 public static void transfer(Account from, Account to, double amount){
          synchronized(lock)
          {
                    from.withdraw(amount);
                    to.deposit(amount);
          }
     }

这种解决方案的问题是私有静态锁限制系统“按顺序”执行传输。

另一种可能是每个帐户都有一个ReentrantLock:

代码语言:javascript
复制
private final Lock lock = new ReentrantLock();




public static void transfer(Account from, Account to, double amount)
{
       while(true)
        {
          if(from.lock.tryLock()){
            try { 
                if (to.lock.tryLock()){
                   try{
                       from.withdraw(amount);
                       to.deposit(amount);
                       break;
                   } 
                   finally {
                       to.lock.unlock();
                   }
                }
           }
           finally {
                from.lock.unlock();
           }

           int n = number.nextInt(1000);
           int TIME = 1000 + n; // 1 second + random delay to prevent livelock
           Thread.sleep(TIME);
        }

 }

这种方法不会发生死锁,因为这些锁永远不会被无限期地持有。如果当前对象的锁被获取,但第二个锁不可用,则释放第一个锁,线程在尝试重新获取锁之前休眠一段指定的时间。

票数 10
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13326861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档