Редактировать: просто чтобы указать, что я знаю, что обычно означает индекс за пределами границ - я бы не делал этот пост, если бы это не было чем-то, с чем я никогда раньше не сталкивался, что в данном случае представляет собой массив список который отказывается добавлять простое старое целое число 6000 или около того и массив байтов размером 2 мил...
Решение. Для всех, кто ищет ответы на этот вопрос, это произошло из-за одновременного добавления нескольких потоков в список, из-за чего он не обновлял новый размер списка должным образом. Чтобы этого избежать, нужно либо синхронизировать ту часть, которая добавляется в список, либо использовать вместо нее что-то вроде Вектора.
У меня есть программа для поиска простых чисел, меньших заданного числа n (решето Эратосфена), которую я распараллелил. В нем я выделил все числа, не являющиеся простыми до n, в массиве байтов, и у меня есть ArrayList, содержащий найденные мной простые числа.
Сначала я просто складываю числа до sqrt(n) и отмечаю все найденные произведения простых чисел (поэтому, если я нахожу 5, я отмечаю: 5*5, и 5*5 + 2*5, и 5*5 + 3*5 и т. д.), так что, найдя все простые числа до квадратного корня из n, я вычеркнул все числа, не являющиеся простыми, между sqrt(n) до n.
На данный момент все, что мне нужно сделать, это просмотреть остальную часть массива байтов и проверить, помечен ли он как простой или нет, и добавить его, если это так. Тем не менее, я получаю исключение индекса за пределами границ в той части, которая добавляет числа, помеченные как простые, в мой ArrayList простых чисел?
public void addRemainingPrimes(int start, int end){
for(int i = start; i < end; i+= 2){
if(isPrime(i)){
primes.add(i);
}
}
}
public boolean isPrime(int i) {
int byteCell = i / 16;
int bit = (i/2) % 8;
return (numbers[byteCell] & (1 << bit)) == 0;
}
В классе потоков:
public void run(){
//does stuff to find primes up to sqrt(n)
updateRange();
addRemainingPrimes(start, end);
}
public void updateRange(){
if(id == 0){
start = sqrt;
}else{
start = (((n - sqrt)/k) * id) + sqrt;
}
if(id == k-1){
end = n;
}else{
end = start + ((n - sqrt) / k) - 1;
}
}
числа — это байтовый массив размера n, простые числа — это мой ArrayList простых чисел, n = 2.000.000, k — количество потоков, которые я использую, а id — от 0 до k-1.
Ошибка, которую я получаю:
Exception in thread "Thread-5" java.lang.ArrayIndexOutOfBoundsException: 6246
at java.util.ArrayList.add(ArrayList.java:463)
at ParallellSieve.addRemainingPrimes(ParallellSieve.java:162)
at ParallellSieve$PrimeWorker.run(ParallellSieve.java:194)
at java.lang.Thread.run(Thread.java:748)
i
?. Оно может быть меньше0
или большеInteger.MAX_VALUE
. проверьте свой с вами отладчик. - person arthur   schedule 22.03.2018