Simple Program using Runnable and Callable

HelloThread1.java

public class HelloThread1 implements Runnable{
    @Override
    public void run() {
        System.out.println("Hello World from Thread Name (" + Thread.currentThread().getName() +") using Runnable ");
    }
}

HelloThread2.java

public class HelloThread2 implements Callable {
    @Override
    public Object call() throws Exception {
        return "Hello World from Thread Name (" + Thread.currentThread().getName() +") using Callable";
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws Exception {
        HelloThread1 objThread1 = new HelloThread1(); //Instance of Runnable
        HelloThread2 objThread2 = new HelloThread2(); //Instance of Callable

        objThread1.run();
        System.out.println(objThread2.call());
    }
}

Output

Hello World from Thread Name (main) using Runnable 
Hello World from Thread Name (main) using Callable

Simple Program to print numbers using threads
NumberPrinter.java

public class NumberPrinter implements Runnable{
    int number;
    public NumberPrinter(int number){
        this.number = number;
    }

    public void run(){
        System.out.println("Printing Number from Thread "+ this.number);
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        for (int idx=1;idx<=5;idx++){
            Thread objthread = new Thread(new NumberPrinter(idx));
            objthread.start();
        }
    }
}

Output

Printing Number from Thread 5
Printing Number from Thread 1
Printing Number from Thread 4
Printing Number from Thread 3
Printing Number from Thread 2

Simple Program using Executor Service taking Runnable as Argument

ExecutorService is a framework which allows to create thread. Threads can be created from FixedThreadPool, CachedThreadPool and ScheduledThreadPool. submit() method takes runnable or callable object (Functional Interface Type) as argument. The Same code above can be rewritten as below
Main.java

public class Main {
    public static void main(String[] args) throws Exception {
        ExecutorService objExecService = Executors.newFixedThreadPool(2);

        //Lambda Expresssion passed as Argument as Runnable is FI
        objExecService.submit(() -> {
            System.out.println(Thread.currentThread().getName());
        });

        objExecService.shutdown();
    }
}

Output

pool-1-thread-1

Same code with Runnable instance passed as argument to submit

  .
  . 
  //Instance of Runnable passed as argument
  HelloThread1 objHT1 = new HelloThread1();
  objExecService.submit(objHT1);
  .
  .

Output

Hello World from Thread Name (pool-1-thread-1) using Runnable 

Same code with Runnable as Anonymous Class passed as argument

ExecutorService exec = Executors.newFixedThreadPool(2);

//Instance of Runnable passed as Anonymous class
exec.execute(new Runnable() {
  public void run() {
    System.out.println("Hello world");
  }
});

exec.shutdown();

Simple Program using Executor Service taking Callable as Argument

public class Main {
    public static void main(String[] args) throws Exception {
        ExecutorService objExecService = Executors.newFixedThreadPool(2);
        Future<String> objFuture = objExecService.submit(new HelloThread2());
        System.out.println(objFuture.get());
        objExecService.shutdown();
    }
}

Output

Hello World from Thread Name (pool-1-thread-1) using Callable

Using Lambda Expression as Submi

.
.
ExecutorService objExecService = Executors.newFixedThreadPool(2);

Future<String> objFuture = objExecService.submit(() -> {
  Thread.sleep(3000);
  return Thread.currentThread().getName();
});

System.out.println(objFuture.get());
.
.

The above could be rewritten in anonymous class as below

ExecutorService objExecService = Executors.newFixedThreadPool(2);

Future<String> objFuture = objExecService.submit(new Callable<String>() {
 @Override
 public String call() throws Exception {
   Thread.sleep(3000);
   return Thread.currentThread().getName();
 }
});

System.out.println(objFuture.get());
objExecService.shutdown();

Program for Creating Thread Pool and executing Task

ThreadPoolExample.java

public class ThreadPoolExample {
    public static void main(String args[]) {
       ExecutorService service = Executors.newFixedThreadPool(10); //create 10 worker threads in Thread Pool
       for (int i =0; i<100; i++){
           service.submit(new Task(i)); //submit that to be done 
       }
       service.shutdown();
    }  
}

Task.java

final class Task implements Runnable {
    private int taskId;  
    public Task(int id){
        this.taskId = id;
    }
  
    @Override
    public void run() {
        System.out.println("Task ID : " + this.taskId +" performed by " 
                           + Thread.currentThread().getName());
    }  
}
Task ID : 0 performed by pool-1-thread-1
Task ID : 3 performed by pool-1-thread-4
Task ID : 2 performed by pool-1-thread-3
Task ID : 1 performed by pool-1-thread-2
Task ID : 5 performed by pool-1-thread-6
Task ID : 4 performed by pool-1-thread-5
  1. NEW – a newly created thread that has not yet started the execution
  2. RUNNABLE – either running or ready for execution but it’s waiting for resource allocation
  3. BLOCKED – waiting to acquire a monitor lock to enter or re-enter a synchronized block/method
  4. WAITING – waiting for some other thread to perform a particular action without any time limit
  5. TIMED_WAITING – waiting for some other thread to perform a specific action for a specified period
  6. TERMINATED – has completed its execution

NEW Thread (or a Born Thread) is a thread that’s been created but not yet started.
It remains in this state until we start it using the start() method

NewState.java

public class NewState implements Runnable{
    public void run(){
        System.out.println("I am in new State");
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
       Thread objThread = new Thread(new NewState());
       System.out.println(objThread.getState());
    }
}

Output

NEW

Runnable When we’ve created a new thread and called the start() method on that, it’s moved from NEW to RUNNABLE state. Threads in this state are either running or ready to run, but
they’re waiting for resource allocation from the system. In a multi-threaded environment, the Thread-Scheduler (which is part of JVM) allocates a fixed amount of time to each thread. So it runs for a particular amount of time, then leaves the control to other RUNNABLE threads.

RunnableState .java

public class RunnableState implements Runnable{
    public void run(){
        System.out.println("I would be in Runnable State");
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
       Thread objRThread = new Thread(new RunnableState());
       objRThread.start();
       System.out.println(objRThread.getState());
    }
}

Output

RUNNABLE
I would be in Runnable State

This is the state of a dead thread. It’s in the TERMINATED state when it has either finished execution or was terminated abnormally.
TerminatedState.java

public class TerminatedState implements Runnable{
    public void run(){
        Thread objNewState = new Thread(new NewState());
        objNewState.start();
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
       Thread objTState = new Thread(new TerminatedState());
       objTState.start();
       objTState.sleep(1000);
       System.out.println("T1 : "+ objTState.getState());
    }
}

Output

I am in new State
T1 : TERMINATED

A thread is in the BLOCKED state when it’s currently not eligible to run. It enters this state when it is waiting for a monitor lock and is trying to access a section of code that is locked by some other thread.
BlockedState.java

public class BlockedState implements Runnable{
    public void run(){
      blockedResource();
    }

    public static synchronized void blockedResource(){
        while(true){
            //Do Nothing
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread objB1Thread = new Thread(new BlockedState());
        Thread objB2Thread = new Thread(new BlockedState());

        objB1Thread.start();
        objB2Thread.start();

        Thread.sleep(1000);

        System.out.println(objB1Thread.getState());
        System.out.println(objB2Thread.getState());
        System.exit(0);
    }
}

Output

RUNNABLE
BLOCKED

A thread is in WAITING state when it’s waiting for some other thread to perform a particular action. According to JavaDocs, any thread can enter this state by calling any one of the following
object.wait() (or) thread.join() (or) LockSupport.park()

WaitingState.java

public class WaitingState implements Runnable{
    public void run(){
        Thread objWaitState = new Thread(new SleepState());

        objWaitState.start();

        try {
            objWaitState.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

SleepState.java

public class SleepState implements Runnable{
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
       Thread objWaitingThread = new Thread(new WaitingState());
       objWaitingThread.start();
       objWaitingThread.sleep(1000);
       System.out.println("T1 : "+ objWaitingThread.getState());
       System.out.println("Main : "+Thread.currentThread().getState());
    }
}

Output

T1 : WAITING
Main : RUNNABLE

A thread is in TIMED_WAITING state when it’s waiting for another thread to perform a particular action within a stipulated amount of time. According to JavaDocs, there are five ways to put a thread on TIMED_WAITING state:
thread.sleep(long millis) (or) wait(int timeout) (or) wait(int timeout, int nanos) thread.join(long millis) (or) LockSupport.parkNanos (or) LockSupport.parkUntil

TimedWaitState.java

public class TimedWaitState implements Runnable{
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread objTWState = new Thread(new TimedWaitState());
        objTWState.start();
        Thread.sleep(2000);
        System.out.println("T1 : "+ objTWState.getState());
    }
}

Output

T1 : TIMED_WAITING