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

标签 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() 调用之间的 ulocked 空间。如何避免读/写问题?

最佳答案

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

remove(index) 是线程安全 pop 函数的一个糟糕的替代品。

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

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

为了使其异常安全。

最后但并非最不重要的一点是,size() 不需要同步。只需返回大小,因为它是只读操作。您可能希望使大小参数可变,但这里并不是特别必要。

关于java - 线程安全字段,避免读写冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33854149/

相关文章:

java - 可以将注入(inject)的 EntityManagers 传递给 EJB bean 的帮助类并使用它吗?

java - 带有连接表的双向 @ManyToOne 创建重复键

javascript - 是否可以从外部暂停/恢复网络 worker ?

.net - Silverlight UI更改会卡住应用程序

java - 使用注释来监视/记录/报告线程访问给定方法的 Java 工具?

ios - iOS-NSCache如何确保线程安全

java - 逗号分隔的整数字符串

java - 创建新 Socket 时添加超时

java - Spring Cloud Data Flow 忽略由 Spring Batch 应用程序配置的数据源

c++ - std::list<std::future> 析构函数不阻塞