0

我正在为学校开发一个 java 项目,你必须处理一个多线程程序。我需要一个类,在许多线程之间共享,它基本上是一个必须管理并发访问的值矩阵,它看起来像:

public class CacheMatrix{
private MyType[][] cachedItems;

public CacheMatrix(int size){
    this.cachedItems = new MyType[size][size];
}
public MyType readItem(int x, int y){...}
public void storeItem(int x, int y, MyType item){...}
}

我正要使用 ReentrantReadWriteLock 矩阵来管理它,每个项目一个,但我意识到矩阵大小约为 10^3 X 10^3 所以我将拥有 100 万个锁!

你认为这是要走的路吗?(创建这么多锁可以吗?)

考虑到使用这个类的线程数被限制在一个小数 N(N 的范围从 2 到 8),你能找到一种更好的方法,它几乎只保留最小互斥但使用更少的锁吗?

感谢您的支持!

4

4 回答 4

1

您可以考虑实施锁条带化以减少锁的数量并保持性能。

mylockscount = min(concurrencylevel, size) 基本上,创建了一个持有锁的内部数组。每当发生读/写操作时,您都会锁定例如mylocks[somehashfunction(x, y) % mylockscount].

这样,锁的数量应该只随着并发线程的数量而不是矩阵的大小而变化。

于 2013-05-28T21:55:01.887 回答
0

我想到了两种可能的情况:

1) 使用单锁。这有点天真,但它可能会解决你的问题。

2) 仅锁定 ROWS 或 COLUMNS。如果您打算一次随机访问一项矩阵,我认为这应该做得很好:

public class CacheMatrix
{
    private MyType[][] cachedItems;

    public CacheMatrix(int size) {
        this.cachedItems = new MyType[size][size];
    }

    public MyType readItem(int x, int y) {
        synchronized (cachedItems[x]) {
            return cachedItems[x][y];
        }
    }

    public void storeItem(int x, int y, MyType item) {
        synchronized (cachedItems[x]) {
            this.cachedItems[x][y] = item;
        }
    }
}
于 2013-05-28T21:33:07.723 回答
0

另一种选择是替换MyType[][]AtomicReference<MyType>[][]; 在这种情况下,如果不等于当前持有的值(在您要调用的表面下),void storeItemboolean storeItem(int x, int y, MyType oldValue, MyType newValue)返回 false 。这样你就没有任何锁了,你只需要实现重试逻辑,以防返回falseoldValue[x][y]AtomicReference#compareAndSet(oldValue, newValue)storeItem

如果MyType是原语,例如int,则使用适当的原子原语,例如,AtomicInteger而不是AtomicReference

于 2013-05-28T21:20:06.297 回答
0

什么是让访问方法同步?

public synchronized MyType readItems(...){...}
于 2013-05-28T21:20:57.497 回答