Reputation: 47
I have written a program that finds the number with the greatest number of divisors from the range 1 to 100,000:
/**
A program that finds the number with the largest number of divisors in the range of 1 to 100,000. This version simply uses threads.
*/
public class ThreadDivisors{
private static final int SAMPLE_SIZE = 100000;
private static final int THREAD_COUNT = 2;
private volatile static int maxDividend;
private volatile static int maxDivisorCount = 0;
public static void main(String[] args){
int start = 1;
int end = SAMPLE_SIZE / THREAD_COUNT;
DivisorThread[] threads = new DivisorThread[THREAD_COUNT];
for(int i = 0; i < THREAD_COUNT; i++){
threads[i] = new DivisorThread(start, end);
System.out.println("Thread created starting at " + start + " and ending at " + end);//debug
start += SAMPLE_SIZE / THREAD_COUNT;
end += SAMPLE_SIZE / THREAD_COUNT;
}
for(int i = 0; i < THREAD_COUNT; i++){
threads[i].start();
}
for(int i = 0; i < THREAD_COUNT; i++){
while(threads[i].isAlive()){
try{
threads[i].join();
}
catch(InterruptedException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
System.out.println("The number with the most divisors is " + maxDividend);
System.out.println(maxDivisorCount);
}
static class DivisorThread extends Thread{
static int start;
static int end;
public DivisorThread(int start, int end){
this.start = start;
this.end = end;
}
public void run(){
System.out.println("Thread running...");
divisorCount(start, end);
}
}
private static void divisorCount(int start, int end){
int divisorCount;//number of divisors for number being divided
int maxThreadDividend = start;
int maxThreadDivisorCount = 0;
for (int dividend = start; dividend <= end; dividend++){//iterate through dividends
divisorCount = 0;
for (int divisor = start; divisor <= dividend; divisor++){//iterate through divisors
if (dividend % divisor == 0){
divisorCount++;
}//end if
}//end for
if (divisorCount > maxThreadDivisorCount){
maxThreadDivisorCount = divisorCount;
maxThreadDividend = dividend;
System.out.println(maxThreadDividend);
System.out.println(maxThreadDivisorCount);
}
}//end for
report(maxThreadDivisorCount, maxThreadDividend);
}
/*This subroutine updates global variables that keep track of which number has the most divisors.*/
private synchronized static void report(int maxThreadDivisorCount, int maxThreadDividend){
if(maxThreadDivisorCount > maxDivisorCount){
maxDivisorCount = maxThreadDivisorCount;
maxDividend = maxThreadDividend;
}
}
}
It works with one thread (the global variable THREAD_COUNT determines this), but not with more. For instance, when I set THREAD_COUNT to 2, I get the following output:
Thread created starting at 1 and ending at 50000 Thread created starting at 50001 and ending at 100000 Thread running... 50001 1 Thread running... 50001 1 The number with the most divisors is 50001 1
The subroutine divisorCount() seems to just stop with the starting point of whatever thread has the largest starting point...it does not go further. What might be causing this problem?
Upvotes: 1
Views: 104
Reputation: 5647
The problem is your inner for loop. Your divisors must not start at start
, but at 1 (or 2 depending on wheter you start the divisor counter with 0 or 1 (or even 2, more later))
That should fix your problem.
On a unrelated note I think you can remove the volatile keyword from your maxDivisor
and maxDividend
variables since all acesses to them are in a synchronized block.
Another thing. There will be no divisors greater than half of the checked dividend (aside from the number itself) Adjusting your limit accordingly should give you a significant performance boost:
for (int dividend = start; dividend <= end; dividend++){
divisorCount = 2;// 1 and dividend are always divisors
for (int divisor = 2; divisor <= dividend / 2; divisor++){
Upvotes: 3