Java 同步对int数组中特定索引的访问

Java 同步对int数组中特定索引的访问,java,arrays,multithreading,Java,Arrays,Multithreading,我使用int数组 我使用该方法在数组中填充索引 public void makeSelectionOfGivenNumber(int number) throws InterruptedException { if (this.table[number]!= 0) { int multiple; multiple = number + number; while (multiple <= upperRange)

我使用int数组

我使用该方法在数组中填充索引

public void makeSelectionOfGivenNumber(int number) throws InterruptedException 
{
    if (this.table[number]!= 0) 
    {
        int multiple;
        multiple = number + number;

        while (multiple <= upperRange) 
        {
            this.table[multiple] = 0;
            multiple += number;
        }
    }
}
public void makeSelectionOfGivenNumber(int number)抛出中断异常
{
如果(此表[编号]!=0)
{
整数倍;
倍数=数字+数字;

while(multiple我认为您需要创建一个额外的锁数组(ReadWriteLock,数组的一个维度就是您想要的)在每次尝试读取/更改目标数组之前,在读取或将元素写入数组时获取锁。要获取锁,需要根据目标数组的所需索引和附加数组的容量计算索引

也许我没有完全正确地理解这项任务

public class SomeTask {

    private final ReadWriteLock[] locks = locks(5);
    private int[] table;
    private int upperRange;

    public SomeTask(int[] table, int upperRange) {
        this.table = table;
        this.upperRange = upperRange;
    }

    public void makeSelectionOfGivenNumber(int number) {
        if (this.table[number] != 0) {
            int multiple;
            multiple = number + number;
            while (multiple <= upperRange) {
                ReadWriteLock lock = getLock(multiple);
                try {
                    lock.writeLock().lock();
                    this.table[multiple] = 0;
                } finally {
                    lock.writeLock().unlock();
                }
                multiple += number;
            }
        }
    }

    private ReadWriteLock getLock(int number) {
        return locks[(locks.length - 1) & number];
    }

    private ReadWriteLock[] locks(int size) {
        ReadWriteLock[] result = new ReadWriteLock[size];
        for (int i = 0; i < size; i++) {
            result[i] = new ReentrantReadWriteLock();
        }
        return result;
    }
公共类任务{
私有最终读写锁[]锁=锁(5);
私有int[]表;
私人整数上限;
公共任务(int[]表,int上限){
this.table=表格;
this.upperRange=upperRange;
}
public void makeSelectionOfGivenNumber(整数){
如果(此表[编号]!=0){
整数倍;
倍数=数字+数字;

而(多个
AtomicIntegerArray
可能就足够了。@Bubletan,使用AtomicIntegerArray和方法集(索引,值)->在特定索引上一次只能有一个线程可以修改值?当然,它不会锁定,但它保证其他线程可以立即看到更改。@Bubletan好吧,但当一个线程从2开始,第二个线程从3开始时,是否会冲突?例如,在6索引上,当它们同时尝试在该索引上写入单元格时?Can AtomicIntergerray排除这种情况?使用table.compareAndSet方法可以解决两个线程对数组中相同索引的访问问题?您能给出一些例子吗?由于您仅在写入时锁定,因此对
此.table[number]的第一次读取访问权!=0
未同步,您可能无法看到另一个线程写入该索引的值。@segabriel,您的解决方案运行良好。性能如何,我已使用开始和结束之间的差分系统.nanoTime检查了时间。在这种情况下,使用线程执行序列任务看起来很糟糕。是否可以提高它?这是task与Erastotenes筛相连接。问题是当一个线程从2开始,第二个线程从5开始时,它们可能同时获得对数字10单元格的访问权限。然而,最后它将是0,但如果我们谈论paraller程序,这是不正确的。@maciejka性能-可能应该添加以下检查
如果(this.table[multiple]!=0)
在尝试获取循环中的锁之前