Я в настоящее время работаю на мое первое многопоточного программного обеспечения - программа, которая вычисляет простые числа ...
В основном я создаю п (число нитей) runnables. Эти runnables добавляются в ArrayList. Они проверяют, является ли число простым. Если число является простым, я добавляю его в длинный массив для последующего использования. Поскольку я хочу, чтобы простые числа были в правильном порядке в этом массиве, мне нужны конкретные потоки, чтобы ждать других. Я делаю это, перебирая ArrayList (см. Выше) и дожидаясь потоков, которые проверяют меньшее число.
После того, как поток сделан, я хочу удалить его из заданного ArrayList, но я не могу, потому что другие потоки все еще проходят через него (Вот почему возникает ConcurrentModificationException, я думаю - это мой первый опыт работы с потоками. ..).Java Тема с ConcurrentModificationException
Я искренне надеюсь, что любой из вас, ребята, может мне помочь :)
Спасибо, очень много!
Matthias
Мой работоспособной класс ( я просто создать четыре объекта этого класса в основном методе):
импорт java.util.ArrayList;
public class PrimeRunnable implements Runnable {
//Static Util
public static ArrayList<PrimeRunnable> runningThreads = new ArrayList<PrimeRunnable>();
public static long[] primes;
public static int nextFreeIndex = 1;
public static long nextPossiblePrime = 3;
//Object specific
private long numberToCheck;
private Thread primeThread;
private String threadName;
private long threadID;
public PrimeRunnable() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
runningThreads.add(this);
}
@Override
public void run() {
boolean isPrime = true;
double sqrtOfPossiblePrime = Math.sqrt(numberToCheck);
long lastDevider = 0;
for(int index = 0; index < nextFreeIndex; index++) {
lastDevider = primes[index];
if(numberToCheck%primes[index] == 0) {
isPrime = false;
break;
}
if(primes[index] > sqrtOfPossiblePrime) {
break;
}
}
while(lastDevider < sqrtOfPossiblePrime) {
lastDevider += 1;
if(numberToCheck%lastDevider == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
//Wait for lower Threads.
for(PrimeRunnable runnable : runningThreads) {
if(runnable.getThreadID() < this.getThreadID()) {
try {
runnable.primeThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
primes[nextFreeIndex] = numberToCheck;
increaseNextFreeIndex();
System.out.println(numberToCheck);
}
runningThreads.remove(this);
}
public void start() {
if(primeThread == null) {
primeThread = new Thread(this, threadName);
}
primeThread.start();
}
public void reset() {
numberToCheck = nextPossiblePrime;
increaseNextPossiblePrime();
threadName = "ThreadToCheck" + numberToCheck;
threadID = numberToCheck;
//No need to readd into runningThread, since we only manipulate an already existing object.
primeThread = new Thread(this, threadName);
primeThread.start();
}
public static void setUpperBorder(int upperBorder) {
if(primes == null) {
primes = new long[upperBorder];
primes[0] = 2;
} else {
System.err.println("You are not allowed to set the upper border while running.");
}
}
public long getNumberToCheck() {
return numberToCheck;
}
private void increaseNextPossiblePrime() {
nextPossiblePrime += 2;
}
private void increaseNextFreeIndex() {
nextFreeIndex += 2;
}
public long getThreadID() {
return threadID;
}
public boolean isAlive() {
return primeThread.isAlive();
}
}
Пожалуйста, пост трассировка стека. – pathfinderelite
Попробуйте использовать потокобезопасные коллекции, такие как Vector или синхронизировать ArrayList runningThreads и long [] primes. –
isma3l
Что-то вызывает подозрение в вашем методе 'start()'. Вы знаете, что «Thread» может быть запущен только один раз? Ваш метод 'PrimeRunnable.start()' выглядит так, как будто вы его называли более одного раза. –