I am trying to calculate all the primes up to an arbitrary number by computing them in parallel. I'm aware that isPrime() can be improved from what it is now, but the main problem is that I can't synchronize access to the ArrayList that is storing the results. I've instantiated a dummy object "m" to serve as a monitor and control access to the array. Obviously I've made a mistake in reasoning somewhere because I get a java.util.ConcurrentModificationException every time. NB: gist
EDIT: updated to show completion after suggestions.
import java.util.ArrayList;
public class Main {
static final int MAX = 100000000;
static final int THREADS = Runtime.getRuntime().availableProcessors();
static final int ARRINITSIZE = 100000;
static ArrayList<Integer> primes = new ArrayList<Integer>(ARRINITSIZE);
public static void main(String[] args) {
Thread[] t = new Thread[THREADS];
PrimeRun.m = new Monitor();
for (int i=0; i<THREADS; i++) {
t[i] = new Thread(new PrimeRun(i) );
t[i].start();
}
// wait for threads to finish
for (int i=0; i<THREADS; i++)
t[i].join();
// NOTE: primes will be out of order because of random thread scheduling
for (int n : primes)
System.out.print("" + n + " ");
System.out.println();
}
static boolean isPrime(int n) {
if (n == 2 || n == 3 || n == 5) return true;
if (n <= 1 || (n&1) == 0) return false;
for (int i = 3; i*i <= n; i += 2)
if (n % i == 0) return false;
return true;
}
synchronized static void addPrime(int n) {
primes.add(n);
}
}
class PrimeRun implements Runnable {
public static Monitor m;
final int ID;
public PrimeRun(int i) {
ID = i;
}
public void run() {
for(int i=0; i < Main.MAX; i++) {
if(i % Main.THREADS == ID)
if(Main.isPrime(i))
m.addPrime(i);
}
}
}
class Monitor {
public synchronized void addPrime(int n) {
Main.addPrime(n);
}
}
I've included my ant script for convenience :)
<project default="cmp">
<target name="cmp"><javac srcdir="." debug="true"/></target>
<target name="run" depends="cmp"><java classname="Main" classpath="."/></target>
<target name="cln"><delete><fileset dir="." includes="*.class"/></delete></target>
</project>