top of page

Welcome
to NumpyNinja Blogs

NumpyNinja: Blogs. Demystifying Tech,

One Blog at a Time.
Millions of views. 

Unveiling the Basics of Thread: A Beginner's Guide

Apr 30, 2025
4 min read

Java is a vast language to explore. Another interesting topic is Threads in Java. Even though threads are considered to be an advanced topic, it is easier to understand..Without further ado, let us dive deep into it..


What is a Thread?

A thread is the execution of a small unit. A process can have many threads. Threads are lightweight processes. Many threads combined together are called a pool of threads. Threads represent a sequence of instructions running in a separate path.


Why do we need Threads?

Threads can share resources. If there is an increment operation, then it has to add one and save the counter every time. Whenever we encounter multitasking, we can use threads. Time-consuming operations like file input /output, network communications, etc., are inconvenient; we can use threads so they do not interfere with other operations.

Every Java program has at least one thread called the main thread or parent thread, whereas other threads are considered child threads.

A thread has these basic components such as

  • Thread ID

  • Program Counter

  • Register

  • Stack



    ThreadID: Each thread has a unique id, so that the operating system can differentiate between the threads.

    Program Counter: Program Counter is a register that stores the memory address of the next instruction that is going to be executed.

    Register: Registers store temporary data or intermediate results for the execution of the thread.

    Stack: The Stack is the memory that is allocated for the variables, function parameters, and return addresses.

There are two ways to implement a thread

  1. Extends the thread class

  2. Implement the runnable interface

By extending the thread class, it is limited to single inheritance, but implementing the Runnable interface is a better option.


Life Cycle Of A Thread

The thread has many states, which are as follows:

  • New

  • Runnable

  • Running

  • Waiting

  • Time waiting

  • Blocked

  • Dead or Terminated


    New Thread:

    When a thread is created, that is when object is created for the thread then it is in the New state. The execution of code has not started. It is waiting to be passed to the runnable stage.


    Runnable State:

    In this stage, the thread has either started execution or is ready to be executed. When the thread scheduler prioritizes this thread, it begins running. After execution, the thread relinquishes the CPU to allow other threads their turn.


    Waiting State:

    In this state, the thread is in a waiting state, waiting for another thread to notify it. When the `wait()` or `join()` method is called, the thread enters the waiting state. If it does not receive a notification, the thread may be terminated.


    Time Waiting State:

    In this state, the thread is in a waiting state with a timeout parameter. It is similar to a waiting state, where it waits till it receives a notification, that is if it is in sleep() or in a conditional wait() method.


    Blocked State:

    In this state, the thread needs to obtain a lock; currently, another thread holds the lock. Therefore, this thread is in a blocked state. It will transition to a runnable state once it acquires the lock.


    Terminated State:

    When the execution of code is finished then it goes to the terminated state, or if there is an error or exception not handled then it goes to the terminated state.


    Life Cycle of A Thread
    Life Cycle of A Thread

    There are a few methods for the execution of the thread.

Thread t=new Thread();//Object is created. the thread is in the New state.
t.start();//It always initiates to execute from start method(means it moves to runnable state)
t.run();//When it is in run method then it is in running state
t.sleep(ms);//Blocked state
t.wait();// waiting state

After the specified milliseconds in the sleep method, it goes to the running stage. After the thread is executed, it moves to a terminated state or stops.


Implementation of a Single Thread:

A single thread can be implemented in two different ways: by extending the thread class or using the Runnable interface. Let us see how we implement by extending the thread class first.

class Single extends Thread
{
public void run()
{
for(int i=0;i<5;i++)
System.out.println(i);
}
}
class ST
{
public static void main(String[args])
{
Single s =new Single();
s.start();
}
}

Here Thread class is a base class that has methods to access. We override the run method to implement whatever we want. Single is a child class where, if we create an object, we will be able to access the methods of the base class. When the start method is called, it automatically goes to the run method, where it overrides the base class run method and executes the given operation. Another way of implementing is by using the Runnable interface. Let us see an example.

class Single implements Runnable
{
public void run()
{
for(int i=0;i<5;i++)
System.out.println(i);
}
}
class ST
{
public static void main(String[args])
{
Single s =new Single();
Thread t=new Thread(s);
t.start();
}
}

We will implement the runnable interface. Interface consists of abstract methods. It has function declarations but not the definitions. Here, in the main method, an object is created for the Single class, but this does not execute the run function. This will be passed as a parameter to the interface. So we have to pass the runnable interface object as a parameter to the thread class, that reference will be assigned to t. The output for both implementations is as follows:

Output:

0

1

2

3

4

Hope you understood better about Threads. Thank you for reading!!!



 
 

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page