Reputation: 351
I'm trying to use multithreading in java to check for prime numbers in a certain range. Depending on many cores my processor has, I need to create threads to do the work. I've 4 cores so I've created four threads. The problem here is that the threads are not alternating while doing their work. What happens is first thread starts and does the work, then the second one starts after the first is done, etc. If I use the sleep method, then I can see the threads alternating but that doesn't seem like multithreading to me. Is there an explanation to that in Java? are they actually working simultaneously under the hood but I can't see it? Thanks in advance, and here's my code:
package multithreading;
import java.util.*;
public class MultithreadingV2{
static ArrayList<Integer> primes = new ArrayList<>();
static int counter = 0;
public static synchronized void primeChecker(int rangeStart, int rangeEnd) throws InterruptedException{
for(int x = rangeStart; x < rangeEnd; x++){
int temp;
boolean isPrime=true;
int numm = x;
Thread.sleep(50);
for(int i=2;i<=numm/2;i++)
{
temp=numm%i;
if(temp==0)
{
isPrime=false;
break;
}
}
if(isPrime){
System.out.println("thread ID: " + Thread.currentThread().getId());
System.out.println(numm + " is a Prime Number");
primes.add(numm);
}
}
}
public static void main(String[] args) throws InterruptedException{
long startTime = System.currentTimeMillis();
ArrayList<Integer> primes = new ArrayList<>();
int processors = Runtime.getRuntime().availableProcessors();
System.out.println("CPU cores: " + processors);
int rangeStart = 2;
int rangeEnd = 1000;
Thread t1 = null;
for(int x = 1; x <= processors; x++){
counter = x;
t1 = new Thread(){
public void run(){
if(counter == 1)
try {
primeChecker(rangeStart, rangeEnd);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
else if(counter == 2)
try {
primeChecker(rangeEnd + 1, rangeEnd * 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
else if(counter == 3)
try {
primeChecker((rangeEnd * 2) + 1, rangeEnd * 3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
else if(counter == 4)
try {
primeChecker((rangeEnd * 3) + 1, rangeEnd * 4);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t1.start();
// t1.join();
}
System.out.println("prime size: " + primes.size());
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println(totalTime);
}
}
Upvotes: 0
Views: 115
Reputation: 719641
The problem is that primeChecker
is a static synchronized
method. This means that when you call it, you acquire a lock that prevents any other thread from calling the method until your call completes. In other words, the calculation will be effectively single-threaded; i.e. no parallelism.
Basically, you need to figure out a better way to synchronize the access / updates to your shared state. One that doesn't prevent other threads from making any progress.
Hint: you only need to synchronize the places where the threads are actually sharing state.
Upvotes: 3