gpt4 book ai didi

java - 是否可以使用两个嵌套的同步块(synchronized block)来锁定数组的两个单元格以进行原子操作?

转载 作者:行者123 更新时间:2023-11-29 07:27:30 26 4
gpt4 key购买 nike

我有一个 Repository 类,它分配表示为 cells 数组字段值的资源。该方法将资源从一个单元移动到另一个单元。

我需要确保当我们将资源从一个单元格移动到另一个单元格时,不能对相关单元格执行其他移动操作。也就是说,如果一个单元格(原始单元格或目标单元格)参与了移动操作,我们必须等到当前操作完成后才能对这些单元格执行另一个移动操作。对不同的单元格对并行执行move应该没有限制,例如,move(cells[1], cells[2], 5)move(cells[4], cells[7], 9) 可以并行执行。

我想使用两个嵌套的 synchronized block 来保护源单元格和目标单元格。我认为我们不需要使用 wait/notifyAll,因为无论如何我们都在使用 synchronized

我走在正确的轨道上吗?

这是代码(moveOriginal 是原始方法,moveSynchronized 是 protected 方法:

public class Repository {
private Integer[] cells;

public Repository(int size, int initialValue) {
cells = new Integer[size];
for(int i = 0; i < size; i++) {
cells[i] = initialValue;
}
}

public void moveOriginal(int from, int to, int amount) {
if(cells[from] >= amount) {
cells[from] = cells[from] - amount;
cells[to] = cells[to] + amount;
}
}

public void moveSynchronized(int from, int to, int amount) {
synchronized(cells[from]) {
synchronized (cells[to]) {
if(cells[from] >= amount) {
cells[from] = cells[from] - amount;
cells[to] = cells[to] + amount;
}
}
}
}
}

最佳答案

不,你不能那样做。为此,您需要锁定数组本身,以防止并行操作。

Integer 是不可变的,这意味着 cells[to] = cells[to] + amount 将不同的对象放在那里,而不是修改 Integer 在里面。当 synchronized(cells[to]) 在不同的时间引用不同的对象时,这将导致问题。

解决此问题的最简单方法是制作一个 Object[] lockArray = new Object[size];Objects 初始化并同步它们。它们不会在您的业务逻辑中发生变化。

在任何情况下,您都需要嵌套的同步 作用域。你还需要做的是 define an order ,例如总是首先同步较小的值。否则,当多个线程尝试执行类似 move(1, 2); 的操作时,您将遇到死锁。同时移动(2, 1);

public void moveSynchronized(int from, int to, int amount) {
if(from == to || from < 0 || to < 0 || from > cells.length || to.cells.length)
throw new IllegalArgumentException("Bad values ! " + from + ", " + to);

// Lock1 is always smaller and locked first
int lock1 = from < to ? from : to;
int lock2 = from < to ? to : from;

synchronized(locks[lock1]) {
synchronized (locks[lock2]) {
if(cells[from] >= amount) {
cells[from] = cells[from] - amount;
cells[to] = cells[to] + amount;
}
}
}
}

关于java - 是否可以使用两个嵌套的同步块(synchronized block)来锁定数组的两个单元格以进行原子操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48905590/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com