线程安全字段,避免读写冲突

时间:2015-11-22 11:18:06

标签: java multithreading thread-safety read-write

我正在尝试编写synccollection 我遇到了读/写问题

我在每个线程中运行此代码

public void run() {
    for (int j = 0; j < threadElemAmount; j++) {
        list.remove((int) (list.size() - 1));
    }
}

并在代码内部编写代码并运行

public T remove(int index){
    lock.lock();
    if (index >= size || index < 0)
        throw new IndexOutOfBoundsException("illegal index value, index = " + index + " size = " + size);
    T removedElement = (T) data[index];
    int movedElementsAmount = size - index - 1;
    //проверить кол-во перемещаемых элементов справа
    if (movedElementsAmount > 0) {
        System.arraycopy(data, index + 1, data, index, movedElementsAmount);
     }
     // очищаем последний
     data[--size] = null;
     lock.unlock();
     return removedElement;    
}

和尺寸

public int size() {
    lock.lock();
    int result = size;
    lock.unlock();
    return result; 
}

我不能使用synchronized关键字这是特殊情况的一部分,只是锁定,它几乎相同。 结果是list.size()来电和list.remove()来电之间最弱的地方。我怎么能避免读/写问题?

2 个答案:

答案 0 :(得分:0)

你需要为pop()编写一个同步函数。

remove(index)是线程安全pop函数的不良替代品。

另外,您应该将代码更改为:

lock.lock()
try {
.
.
.
} finally {
    lock.unlock();
}

为了使其异常安全。

最后但并非最不重要的是,size()不需要同步。只需返回大小,因为它是一个只读操作。您可能希望将size参数设置为volatile,但此处并不特别需要。

答案 1 :(得分:0)

您的选择是;

  • 暴露锁定,以便在两个选项中都能保持锁定。
  • 使用与可见的锁定同步。
  • 添加removeLast()操作。
  • 添加drainTo()操作。
  • 使用其中一个内置的线程安全集合,它已经这样做了。

看起来你想要消耗N个物体,所以最后一个选项可能是最好的。