### Question:
MultithreadedSumCalculation { public static long getSum(final long[] array, int nThreads) { if (array == null) { throw new IllegalArgumentException("Input array should be not null"); } if (nThreads <= 0) { throw new IllegalArgumentException("Number of threads should be positive"); } if (array.length == 0) { return 0; } else if (array.length == 1) { return array[0]; } nThreads = min(nThreads, array.length); final ExecutorService executor = Executors.newFixedThreadPool(nThreads); int step = array.length / nThreads; if (array.length % nThreads > 0) { step++; } Future<Long>[] futures = new Future[nThreads]; for (int i = 0; i < nThreads; i++) { int fromInclusive = i * step; int toExclusive = min(fromInclusive + step, array.length); futures[i] = executor.submit(() -> calculate(array, fromInclusive, toExclusive)); } executor.shutdown(); long totalSum = 0; for (int i = 0; i < nThreads; i++) { try { totalSum += futures[i].get(); } catch (ExecutionException ex) { Throwable t = ex.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw (Error) t; } } catch (InterruptedException ignored) { throw new RuntimeException("Execution was interrupted"); } } return totalSum; }  static long getSum(final long[] array, int nThreads);  }### Answer:
@Test(expected = IllegalArgumentException.class) public void testGetSumNullArray() { getSum(null, 5); }
@Test(expected = IllegalArgumentException.class) public void testGetSumNonPositiveThreads() { getSum(new long[]{1, 2}, 0); }
@Test public void testGetSum() { assertThat(getSum(new long[0], 5), is(0L)); assertThat(getSum(new long[]{2}, 5), is(2L)); assertThat(getSum(new long[]{2, 3, 5}, 100), is(10L)); long[] array = new long[1000]; for (int i = 0; i < array.length; i++) { array[i] = i; } for (int i = 1; i <= 100; i++) { assertThat(getSum(array, i), is(499500L)); } }