output of a program running 3 threads created by extending Thread class

I am new to Java Multi-threading and trying to figure out the output of below code that creates 3 threads a, b and c.

class A extends Thread {
    int i = 0;

    public void run() {
        System.out.println("Thread A started");
        while (i < 4) {
            System.out.println("t value of i in Thread A:" + i);
            i++;
        }
        System.out.println("ThreadA finished");
    }
}

class B extends Thread {
    public void run() {
        int i = 0;
        System.out.println("ThreadB started");
        while (i < 4) {
            System.out.println("t value of i in Thread B:" + i);
            i++;
        }
        System.out.println("ThreadB finished");
    }
}

class C extends Thread {
    public void run() {
        int i = 0;
        System.out.println("ThreadC started");
        while (i < 4) {
            System.out.println("t value of i in Thread C" + i);
            i++;
        }
        System.out.println("ThreadC finished");
    }
}

public class App {
    public static void main(String[] args) throws Exception {
        // System.out.println("Hello, World!");

        System.out.println("Main Thread started");
        A a = new A();
        B b = new B();
        C c = new C();
        Thread th = Thread.currentThread();
        System.out.println(th.getName());
        System.out.println(th.getPriority());
        System.out.println("Priority of A thread " + a.getPriority());
        System.out.println("Priority of B thread " + b.getPriority());
        System.out.println("Priority of C thread " + c.getPriority());
        System.out.println();
        th.setPriority(Thread.MAX_PRIORITY);
        b.setPriority(Thread.MIN_PRIORITY);
        c.setPriority(Thread.NORM_PRIORITY);
        System.out.println("Showing new Priorites n");
        System.out.println("Priority of TH thread " + th.getPriority());
        System.out.println("Priority of A thread " + a.getPriority());
        System.out.println("Priority of B thread " + b.getPriority());
        System.out.println("Priority of C thread " + c.getPriority());
        System.out.println();
        a.start();
        b.start();
        c.start();
    }
}

output of above code is

Main Thread started
main
5
Priority of A thread 5
Priority of B thread 5
Priority of C thread 5

Showing new Priorites

Priority of TH thread 10
Priority of A thread 5
Priority of B thread 1
Priority of C thread 5

ThreadC started
         value of i in Thread C0
Thread A started
         value of i in Thread A:0
         value of i in Thread A:1
         value of i in Thread C1
         value of i in Thread C2
         value of i in Thread C3
ThreadC finished
ThreadB started
         value of i in Thread A:2
         value of i in Thread A:3
ThreadA finished
         value of i in Thread B:0
         value of i in Thread B:1
         value of i in Thread B:2
         value of i in Thread B:3
ThreadB finished

I know that after calling start() method, threads become runnable and ready to be picked by thread scheduler.

From output we can see thread C started running its run() method first, then it should have completed its run() method. But how does run() method of thread a is executing before completion of run() method of thread C? Somebody please help here.

Answer

You should not rely on thread priorities. This is what the Oracle JRockit documentation says:

Don’t Depend on Thread Priorities

Be careful when using java.lang.Thread.setPriority. Depending on thread priorities might lead on unwanted or unexpected results since the scheduling algorithm might choose to starve lower priority threads of CPU time and never execute them. Furthermore the result might differ between operating systems and JVMs.

The Java API specification states that “Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.”

The priority set by the setPriority() method is a parameter that might be used in the thread-scheduling algorithm, which shares CPU execution time between executing threads. This algorithm might be controlled either by the JVM or by the operating system. It is important to be aware of the fact that this algorithm normally differs between operating systems and that the algorithm might change between releases of both the operating system and the JVM. For BEA JRockit JVM native threads, the algorithm is implemented by the operating system.

What you have observed is the effects of the system specific behavior of thread scheduling … as described by the above documentation (for example).