首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SharedArray死锁和raise条件

SharedArray死锁和raise条件
EN

Stack Overflow用户
提问于 2019-05-21 19:18:43
回答 2查看 94关注 0票数 0

我正在尝试使用可重入锁来模拟共享数组中的死锁场景。

代码语言:javascript
复制
class SharedArray { 
    private int ff[];
    private Lock keys[];        

    public SharedArray(int n){
        ff = new int[n];
        keys = new ReentrantLock[n];
        for(int j = 0; j < n; j++){
            ff[j] = (int)(Math.random()*100);
            keys[j] = new ReentrantLock();
        }
    }

    void swap(int j, int k) { 
        keys[j].lock(); keys[k].lock(); 
        int t = ff[j]; ff[j] = ff[k]; ff[k] = t;
        keys[j].unlock(); keys[k].unlock(); 
    }       
}

在这里,交换方法很容易死锁,这是我已经实现的。例如,如果线程1是交换(7,4),同时线程2是交换(4,7),这将引发死锁。

我如何防止它死锁。需要什么样的重构。我曾尝试使用同步,但我正在寻找一种可能可靠的方法来解决这个问题。

代码语言:javascript
复制
synchronized void swap(int j, int k) { 
    keys[j].lock(); keys[k].lock(); 
    int t = ff[j]; ff[j] = ff[k]; ff[k] = t;
    keys[j].unlock(); keys[k].unlock(); 
} 
EN

回答 2

Stack Overflow用户

发布于 2019-05-21 21:49:35

如何防止死锁?

防止死锁的一种方法是确保获取相同两个锁的任何线程始终以相同的顺序获取它们。

代码语言:javascript
复制
void swap(int j, int k) {
    int first = Math.min(j, k);
    int second = Math.max(j, k);
    keys[first].lock(); keys[second].lock(); 
    int t = ff[j]; ff[j] = ff[k]; ff[k] = t;
    keys[second].unlock(); keys[first].unlock(); 
}
票数 0
EN

Stack Overflow用户

发布于 2019-05-21 21:51:46

您想要使用锁排序。如果您每次都以可预测的顺序锁定,则可以防止死锁。

在Java并发性实践中,您可以看到一个如何实现这一点的示例:

代码语言:javascript
复制
public void transferMoney(final Account fromAcct, final Account toAcct, final DollarAmount amount)
        throws InsufficientFundsException {
    class Helper {
        public void transfer() throws InsufficientFundsException {
            if (fromAcct.getBalance().compareTo(amount) < 0)
                throw new InsufficientFundsException();
            else {
                fromAcct.debit(amount);
                toAcct.credit(amount);
            }
        }
    }
    int fromHash = System.identityHashCode(fromAcct);
    int toHash = System.identityHashCode(toAcct);
    if (fromHash < toHash) {
        synchronized (fromAcct) {
            synchronized (toAcct) {
                new Helper().transfer();
            }
        }
    } else if (fromHash > toHash) {
        synchronized (toAcct) {
            synchronized (fromAcct) {
                new Helper().transfer();
            }
        }
    } else {
        synchronized (tieLock) {
            synchronized (fromAcct) {
                synchronized (toAcct) {
                    new Helper().transfer();
                }
            }
        }
    }
}

https://pdfs.semanticscholar.org/3650/4bc31d3b2c5c00e5bfee28ffc5d403cc8edd.pdf,搜索清单10.3。诱导Lock排序以避免死锁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56237133

复制
相关文章

相似问题

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