Multi-threading in Java

There are 2 ways in which we can do multi-tasking in computer systems.

  1. Process based multi-tasking
  2. Thread based multi-tasking

Java has a very good support for multi-threading based multi-tasking. Multi threading is used when you need to execute the independent jobs within same program simultaneously.

Usually, our code is run in sequential manner – one line at a time. There is just a single flow (Also called as Main Thread). With threads, we can have multiple flows of the execution. Remember that Multi-threading is mostly useful in scenarios where we have multiple independent jobs.

Thread Life Cycle

A thread follows typical life cycle as shown in below image. Start() method invokes run method and thread is put in running state.  Thread can go into not running state due to many reasons as mentioned below.

  1. sleep method is called (Stops the execution of current thread for specific duration)
  2. yield method is called (Suspends execution of current thread and gives other threads a chance to run)
  3. wait method is called (Waits for other thread to release a lock)
  4. join method is called (waits until other thread finishes execution)
  5. waiting for I/O operation to finish

A thread will start running once any of the above operation is complete. Thread scheduler decides which thread has to be started and when.

Each thread dies at the end of cycle and goes to dead state.

Thread Priority

Each thread has got the normal priority (5). But we can change the priority of thread. Suppose there are 2 thread t1 and t2. You want to run t2 before t1. Then you will have to set the t2’s priority higher than t1. If we set t2’s priority  as 6, then t2 will run before t1

Creating a thread

There are 2 ways in which we can create threads in Java.

  1. By extending Thread class
  2. By implementing Runnable interface

Difference between these 2 approaches is that when we create a thread by extending a Thread, we can not extend any other class thus we can not use inheritance in first method. While in second method, we can extend any other class.

Threads by extending the Thread class.

In this approach, we have to create a class which extends a thread and then create a run method in it which performs a specific job. Let us say we need to perform 2 tasks – print squares of 1 – 10 and print cubes of 1 – 10. So Both the jobs are independent of each other. We can have first thread printing squares and other thread printing cubes simultaneously.

package corejava;

/**
 * Created by Sagar on 10-04-2016.
 */
public class ThreadingClass {

    public static void main(String [] args){
        SquareThread t1 = new SquareThread();
        CubeThread t2 = new CubeThread();
        t1.start();
        t2.start();
    }
}

class SquareThread extends Thread{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println("SquareThread -> " + i*i);
        }
    }
}

class CubeThread extends Thread{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println("CubeThread -> " + i*i*i);
        }
    }
}

Here is the sample output of above code.

SquareThread -> 1
SquareThread -> 4
SquareThread -> 9
SquareThread -> 16
CubeThread -> 1
SquareThread -> 25
CubeThread -> 8
SquareThread -> 36
CubeThread -> 27
SquareThread -> 49
CubeThread -> 64
SquareThread -> 64
CubeThread -> 125
SquareThread -> 81
CubeThread -> 216
SquareThread -> 100
CubeThread -> 343
CubeThread -> 512
CubeThread -> 729
CubeThread -> 1000

Process finished with exit code 0

Threads by implementing Runnable interface.

package corejava;

/**
 * Created by Sagar on 10-04-2016.
 */
public class ThreadingByRunnable {
    public static void main(String [] args) {
        NewSquareThread st = new NewSquareThread();
        Thread t1 = new Thread(st);
        NewCubeThread ct = new NewCubeThread();
        Thread t2 = new Thread(ct);
        t1.start();
        t2.start();
    }
}

class NewSquareThread implements Runnable{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println("NewSquareThread -> " + i*i);
        }
    }
}

class NewCubeThread implements Runnable{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println("NewCubeThread -> " + i*i*i);
        }
    }
}

You may also like...