0

我需要一个 AtomicByteArray 用于以 Java 的AtomicIntegerArray为模型的内存关键型应用程序。我的实现将四个字节包装成一个整数并使用 AtomicIntegerArray。

实现很简单,get()andset()实现相当简单。比较compareAndSwap()棘手。我的实现如下所示(它在单线程中工作得很好)。

我正在尝试确定比赛条件。get()一种可能的情况是,值在对and的调用之间发生了变化和交换compareAndSet(),但这似乎是无害的。

我错过了任何可能出错的事情吗?

/**
 * Atomically sets the element at position {@code i} to the given
 * updated value if the current value {@code ==} the expected value.
 *
 * @param i the index
 * @param expect the expected value
 * @param update the new value
 * @return true if successful. False return indicates that
 * the actual value was not equal to the expected value.
 */
public boolean compareAndSet(final int i, final byte expected, final byte val) {
    int idx = i >>> 2;
    int shift = (i & 3) << 3;

    while (true) {
        final int num = this.array.get(idx);
        // Check that the read byte is what we expected
        if ((byte)(num >> shift) != expected) {
            return false;
        }
        // If we complete successfully, all is good
        final int num2 = (num & ~(0xff << shift)) | ((val & 0xff) << shift);
        if ((num == num2) || this.array.compareAndSet(idx, num, num2)) {
            return true;
        }
    }
}

更新:我已经实现了AtomicByteArray的基本版本,它集成了以下答案中的改进。

4

1 回答 1

1

您可以考虑使用口罩。这可能更快/更清洁。

int idx = i >>> 2;
int shift = (i & 3) << 3;
int mask = 0xFF << shift;
int expected2 = (expected & 0xff) << shift;
int val2 = (val & 0xff) << shift;

while (true) {
    final int num = this.array.get(idx);
    // Check that the read byte is what we expected
    if ((num & mask) != expected2) return false;
    // If we complete successfully, all is good
    final int num2 = (num & ~mask) | val2;
    if ((num == num2) || this.array.compareAndSet(idx, num, num2)) {
        return true;
    }
}

您希望在循环内做最少的工作,以便如果存在争用,您可以尽快重试。

我不确定num == num2帮助大于伤害。我建议你试试不做比较。

于 2014-06-13T19:51:27.570 回答