Q:

Why does it take different times to execute threads of the same behavior?

I'm new to multithreading. I have a program that consists of two classes: PrimeNumber and a main class. I'm trying to find all the prime numbers in a given range.
Here's my PrimeNumber class:
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class PrimeNumber extends Thread{

    int start, end;
    int threadNumber; //used to display the thread number
    static ArrayList<Integer> list  = new ArrayList<Integer>(1000000);

    public PrimeNumber(int start, int end, int threadNumber) {
        this.start = start;
        this.end = end;
        this.threadNumber = threadNumber;
          // added code
            if(list.isEmpty()){
            list.add(2);
        }

    }
    @Override
    public void run(){
        long startTime = System.nanoTime();
        System.out.println(threadNumber + " started");
        for(int i = start; i<=end;i++){
            if(isPrime(i)){
                list.add(i);
            }

        }
        System.out.println(threadNumber + " has finished");
        long endTime = System.nanoTime();

        System.out.println("Time for thread " + threadNumber + " is " +TimeUnit.SECONDS.convert(endTime-startTime, TimeUnit.NANOSECONDS) + " seconds.");

    }  

//modified method
/**
 *  Determine whether a number is prime 
 * @param number
 * @return true if number is prime, false otherwise
 */

     public boolean isPrime(int number){
        if(number == 0 || number == 1){
            return false;
        }

        else {
            int counter = 0;
            while(counter<list.size()){
                if(number%list.get(counter)==0){
                    return false;
                }
                counter++;
            }
        }

        return true;
    }
  }

and here's my main class
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

public class MainClass {

    public static void main(String[] args) throws InterruptedException{
        final int maxNumberOfThreads = 3; // number of threads I want to create
        final int maxNumber = 900000;   // Max range for which I'm finding all the prime numbers up to it
        int initialNumber = 1;
        ArrayList<Thread> myList = new ArrayList<Thread>();
        for(int i = 0; i < maxNumberOfThreads; i++ ){
            myList.add(new PrimeNumber(initialNumber, initialNumber+ maxNumber/maxNumberOfThreads, i+1));
            myList.get(i).start();
            initialNumber+=maxNumber/maxNumberOfThreads;
        }

        for(Thread thread : myList){

            thread.join();
        }
        try {
            Collections.sort(PrimeNumber.list); // sort the list
            BufferedWriter writer = new BufferedWriter(new FileWriter(new File("Primes.txt"),true));
            for(int i = 0; i <PrimeNumber.list.size(); i++){
                writer.write(PrimeNumber.list.get(i).toString());
                //System.out.println(PrimeNumber.list.get(i));
                writer.newLine();
            }
            writer.close();
            System.out.println("Done writing to the file");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

When I run my program here's the output I get:
2 started
3 started
1 started
1 has finished
Time for thread 1 is 3 seconds.
2 has finished
Time for thread 2 is 7 seconds.
3 has finished
Time for thread 3 is 11 seconds.
Done writing to the file

Even though the threads have similar behaviors (they all calculate the prime numbers on almost identical ranges) why is the execution time different for each thread?
I've searched for quite some time but didn't find a satisfying answer. Thanks in advance.
Edit: I've added a step in my isPrime() method which improved the execution time greatly.

A:

This loop in method isPrime performs more iterations on thread 3 than on thread 2, and more iterations on thread 2 than on thread 1, since numbers tested are different in each case:
     for(int i = 2; i< number; i++)
    {
        if(number%i ==0){
            return false;
        }
    }
    return true;

Also, the number of primes in each of the three ranges is different, so the number of additions to the list will be different too.

