Using 10 Threads to Process an Array

This is a VERY basic example which demonstrates the basic concepts of creating and running threads which process a given range of values from a specific array. The example makes a few assumptions (only a even number of elements for example). The example is also slightly long winded and is done so deliberately, in an attempt to demonstrate the basic steps which would be needed

Start by taking a look at the Concurrency Trail for more details

import java.util.Random;

public class ThreadExample {

    public static void main(String[] args) {
        int[] numbers = new int[100000];
        Random rnd = new Random();
        for (int index = 0; index < numbers.length; index++) {
            numbers[index] = rnd.nextInt();
        }

        Thread[] threads = new Thread[10];
        Worker[] workers = new Worker[10];

        int range = numbers.length / 10;
        for (int index = 0; index < 10; index++) {
            int startAt = index * range;
            int endAt = startAt + range;
            workers[index] = new Worker(startAt, endAt, numbers);
        }

        for (int index = 0; index < 10; index++) {
            threads[index] = new Thread(workers[index]);
            threads[index].start();
        }

        boolean isProcessing = false;
        do {
            isProcessing = false;
            for (Thread t : threads) {
                if (t.isAlive()) {
                    isProcessing = true;
                    break;
                }
            }
        } while (isProcessing);

        for (Worker worker : workers) {
            System.out.println("Max = " + worker.getMax());
        }

    }

    public static class Worker implements Runnable {

        private int startAt;
        private int endAt;
        private int numbers[];

        private int max = Integer.MIN_VALUE;

        public Worker(int startAt, int endAt, int[] numbers) {
            this.startAt = startAt;
            this.endAt = endAt;
            this.numbers = numbers;
        }

        @Override
        public void run() {
            for (int index = startAt; index < endAt; index++) {
                max = Math.max(numbers[index], max);
            }
        }

        public int getMax() {
            return max;
        }

    }

}

A slightly simpler solution would involve the ExecutorService API, which would allow you to offer a series of Callables to the service which would then return a List of Future's. The benefit here is, the service won't return till all the Callables have completed (or have failed), so you don't need constantly check the states of the threads

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ThreadExample {

    public static void main(String[] args) {
        int[] numbers = new int[100000];
        Random rnd = new Random();
        for (int index = 0; index < numbers.length; index++) {
            numbers[index] = rnd.nextInt();
        }

        ExecutorService executor = Executors.newFixedThreadPool(10);

        Worker[] workers = new Worker[10];

        int range = numbers.length / 10;
        for (int index = 0; index < 10; index++) {
            int startAt = index * range;
            int endAt = startAt + range;
            workers[index] = new Worker(startAt, endAt, numbers);
        }

        try {
            List<Future<Integer>> results = executor.invokeAll(Arrays.asList(workers));
            for (Future<Integer> future : results) {
                System.out.println(future.get());
            }
        } catch (InterruptedException | ExecutionException ex) {
            ex.printStackTrace();
        }

    }

    public static class Worker implements Callable<Integer> {

        private int startAt;
        private int endAt;
        private int numbers[];


        public Worker(int startAt, int endAt, int[] numbers) {
            this.startAt = startAt;
            this.endAt = endAt;
            this.numbers = numbers;
        }

        @Override
        public Integer call() throws Exception {
            int max = Integer.MIN_VALUE;
            for (int index = startAt; index < endAt; index++) {
                max = Math.max(numbers[index], max);
            }
            return max;
        }

    }

}