public static void problem3(Long aNumber, Integer numberOfThreads) throws InterruptedException, ExecutionException
{
final ExecutorService service;
long executionTime;
long startTime = System.currentTimeMillis();
long finishTime = 0;
service = Executors.newFixedThreadPool(numberOfThreads);
List<List> resultsLists = new ArrayList<>();
List <FutureTask<List>> taskList = new ArrayList<>();
List<Problem3Thread> threadsList = new ArrayList<>();
Boolean addToFinal;
Long addToFinalNumber;
//half the number because nothing over halfway will divide
Long numberHalved = (aNumber / 2) + 1;
//each thread needs a range to work on, this will be the increment between
//ranges for each thread
Long numberForThreads = numberHalved / numberOfThreads;
//to avoid loss due to division add to the final number of
// the last thread to execute
addToFinalNumber = numberHalved % numberOfThreads;
if (addToFinalNumber == 0)
{
addToFinal = false;
}
else
{
addToFinal = true;
}
//create a number of threads to operate on a different range of the number
//this will speed up calculation time on larger numbers
int count = 0;
Long currentStart = 3L;
Long currentFinish = numberForThreads;
while (count < numberOfThreads)
{
threadsList.add(new Problem3Thread(currentStart, currentFinish, aNumber));
//to avoid loss due to division add to the final number of
// the last thread to execute, this is where it is added
if (count + 2 == numberOfThreads && addToFinal)
{
currentStart = currentFinish;
currentFinish = currentFinish + numberForThreads + addToFinalNumber;
}
else
{
currentStart = currentFinish;
currentFinish = currentFinish + numberForThreads;
}
count++;
}
//create tasks for each thread, this is needed when using callable
//instead of runnable
for (Problem3Thread aThread : threadsList)
{
taskList.add(new FutureTask<>(aThread));
}
//start each task
for (FutureTask aTask : taskList)
{
service.submit(aTask);
}
//get results from each task
for (FutureTask aTask : taskList)
{
resultsLists.add((List<Long>) aTask.get());
}
service.shutdown();
//format the results by putting them all in a set to remove any
// possible duplicates
Iterator resultsIterator = resultsLists.iterator();
Set<Long> finalResults = new HashSet<>();
while (resultsIterator.hasNext())
{
List<Long> aResultsList = (List<Long>) resultsIterator.next();
finalResults.addAll(aResultsList);
}
//find the largest prime factor out of the results
Long currentLargest = 0L;
for (Long aLong : finalResults)
{
if (aLong > currentLargest)
{
currentLargest = aLong;
}
}
//if there were no results but it was an even number the largest prime
// factor was 2
if (finalResults.isEmpty() && aNumber % 2 == 0)
{
System.out.println("The largest prime factor was: " + 2);
}
else
{
System.out.println("The prime factors were: " + finalResults);
System.out.println("The largest prime factor was: " + currentLargest);
service.shutdown();
finishTime = System.currentTimeMillis();
executionTime = finishTime - startTime;
System.out.println("Execution time: " + executionTime);
}
}