# Using threads to calculate the average

• 06-18-2010, 12:54 PM
gish
Using threads to calculate the average
Hi all, I want to find the average of n numbers using three threads. This is the code that I have tried for. But I don't know to continue on it. Please help.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.*;

class MyRunnable implements Runnable {

private final long countUntil;

MyRunnable(long countUntil) {
this.countUntil = countUntil;
}

@Override
public void run() {
long sum = 0;
long average =0;
for (long i = 1; i < countUntil; i++) {
sum += i;
average = sum/i;
}
System.out.println(average);
}
}

public class Main1 {
private static final int NTHREDS = 3;

public static void main(String[] args) {
System.out.println("Enter a number");
String line = null;
int val = 0;
try {
val = Integer.parseInt(line);
} catch (NumberFormatException ex) {
System.err.println("Not a valid number: " + line);
} catch (IOException e) {
System.err.println("Unexpected IO ERROR: " + e);
}

for (int i = 0; i < 3; i++) {
Runnable worker = new MyRunnable(10L+i);
executor.execute(worker);
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {

}
}
}
• 06-18-2010, 01:15 PM
Norm
Quote:

I want to find the average of n numbers using three threads
Why do you need 3 threads to do this?
• 06-18-2010, 01:39 PM
gish
Hi.. This is an assignment given for Concurrent Programming. My design is when the user input the numbers add them in to a list and devide the list in to three and assign each thread to calculate the sum and finally average.

Thanks
• 06-18-2010, 01:42 PM
Norm
Please use the [ code] tags on your code to preserve the formatting. Unformatted code is hard to read.

The code you posted does not compile without errors.
• 06-18-2010, 01:46 PM
gish
ok...sorry for tht... can u tell me how to devide that number in to 3segments and assign each thread?
• 06-18-2010, 01:51 PM
Norm
Quote:

how to divide that number in to 3 segments
Take total length of list and divide by 3
Pass starting position and number of items to be processed to the working method.
For example For a list of 9 items: 0 for 3(items 0,1,2), 3 for 3(3,4,5) and 6 for 3(6,7,8)
If the length of list not divisible by 3, give one thread the remaining
• 06-18-2010, 02:19 PM
JosAH
Quote:

Originally Posted by Norm
If the length of list not divisible by 3, give one thread the remaining

Be careful with that; you have to keep track of the total number of numbers you have fed to each thread. Better pad the sequence of numbers with zeros so each thread can calculate its own average and the controlling thread just has to sum those averages and divide the sum by three.

kind regards,

Jos (<--- micro optimizer ;-)
• 06-18-2010, 05:18 PM
gish
Thanks for the replies. Can you give me a code example for passing the devided list in to threads?
• 06-18-2010, 06:16 PM
Norm
Quote:

Better pad the sequence of numbers with zeros
Or pass the divisor(total count) as arg to the method.

object.method(array, start, count); // call the method

public int method(int[] ar, int start, int count) { ...} // define the method
• 06-18-2010, 07:10 PM
gish
Hi.. Thanks for the reply Norm. This is what I did.

int count = numbers.size();
int pointer = count/3;
int remainder = count%3;
for (int i = 0; i < 3; i++){
// adding the values in segment 1
if (i == 0){
mc1.start();
}
else if (i==1){
mc2.start();
}
else
mc3.start();
}

Here I'm getting an error at Thread mc3 as "Thread can't be resolved". Could you please tell me why?
• 06-18-2010, 07:16 PM
Norm
Quote:

I'm getting an error
Please copy and post the full text of the error message here.

Also please use code tags to keep code formatting.
• 06-18-2010, 08:05 PM
gish
Hi..sorry for the same mistake. I have found the error, just missing a bracket. Thanks for the help.
• 06-18-2010, 08:08 PM
Norm
Quote:

Better pad the sequence of numbers with zeros so each thread can calculate its own average and the controlling thread just has to sum those averages and divide the sum by three.
I think we've been asleep on this bit.
For example, take a list of numbers all the same value. Any subpart's average will be the number. If there are n subparts, each will have the same average. Add together the n subparts averages and divide by n and you get the number. With padding the average of that subpart will be different than the number.
• 06-18-2010, 09:23 PM
JosAH
Quote:

Originally Posted by Norm
I think we've been asleep on this bit.
For example, take a list of numbers all the same value. Any subpart's average will be the number. If there are n subparts, each will have the same average. Add together the n subparts averages and divide by n and you get the number. With padding the average of that subpart will be different than the number.

But now take a bunch of unequal numbers and not a multiple of three numbers in total ...

kind regards,

Jos

ps. agreed, I've been sleeping too but it was Friday afternoon ;-)
• 06-18-2010, 11:10 PM
Norm
Is there a way to partition a set into unequal groups and and get the correct answer?
Put some math on this.
• 06-19-2010, 05:23 AM
gish
I am still confused about the way to do this in threads. should we have to put that method as run method? If else what we have to put in the run method of each thread?
Thnanks.
• 06-19-2010, 12:26 PM
Norm
@JosAH
Quote:

But now take a bunch of unequal numbers and not a multiple of three numbers in total
To merge the averages returned by the n threads, sum up the average from each thread times the number of items it had, add these to the total and divide by the total items in the list: Avg = (avg_p1*nbr_p1 + avg+p2*nbr_p2 + ... avg_pn*nbr_pn) / total nbr

@OP back to the problem
Create a class for each Averager class, have the class extend Runnable (has run method), save references to class objects,
pass the array of number, starting index and count to constructor and start a Thread with the class. The class should have a get method to return the results.
Next problem I'll have to research is how the controlling thread waits for all the worker threads to finish before doing the final total. There are some classes that do this for you.
• 06-19-2010, 01:08 PM
gish
• 06-19-2010, 02:42 PM
JosAH
Quote:

Originally Posted by Norm
@JosAH

To merge the averages returned by the n threads, sum up the average from each thread times the number of items it had, add these to the total and divide by the total items in the list: Avg = (avg_p1*nbr_p1 + avg+p2*nbr_p2 + ... avg_pn*nbr_pn) / total nbr

<hijacking a bit further>
But then there is no need for the threads to divide their total by their number of numbers and the 'main' thread could simply add those three totals and divide by nbr
</hijacking a bit further>

kind regards,

Jos
• 06-19-2010, 02:57 PM
Norm
<hijacking a bit further>
OK. That redefines the function of the threads: They sum their list vs computing its average.
</hijacking a bit further>