import java.util.Random;
import java.util.Scanner;

/**
 * Class that demonstrates Java threads for coordination synchronization.
 *   @author Dave Reed
 *   @version 4/12/17
 */
public class ArraySum {
	
	/**
	 *  Calculates the sum of the numbers in the array.
     *   @param a the array of numbers
	 *   @param threadCount the number of separate threads that can be spawned
	 *   @return the sum of the numbers
	 */
	public static int sumConcurrently(int[] a, int threadCount) {
		int len = (int) Math.ceil(1.0 * a.length / threadCount);
		Thread[] threads = new Thread[threadCount];
		for (int i = 0; i < threadCount; i++) {
			threads[i] = new SumThread(a, i*len, Math.min((i+1)*len, a.length));
			threads[i].start();
		}
		try {
			for (Thread t : threads) {
				t.join();
			}
		} catch (InterruptedException ie) {}
		
		int total = 0;
		for (Thread summer : threads) {
			total += ((SumThread)summer).getSum();
		}
		return total;
	}
	
	////////////////////////////////////////////////////////////////////////
	
    public static void main(String[] args) {
		Random randy = new Random();
		int size = 1000;

		System.out.println("Enter number of threads: ");
		Scanner input = new Scanner(System.in);
		int numThreads = input.nextInt();
		input.close();
		
		while (true) {
			int[] nums = new int[size];
			for (int j = 0; j < size; j++) {
				nums[j] = randy.nextInt();
			}

			long startTime1 = System.currentTimeMillis();
			int total = 0;
			for (int j = 1; j <= 1000; j++) {
				total = sumConcurrently(nums, numThreads);
			}
			long endTime1 = System.currentTimeMillis();
			

			System.out.printf("%10d elements  =>  %6d microsec \n", size, endTime1 - startTime1);
			size *= 2; 
		}
    }
	

}