threads in java

Java Threads – Do you know the basics?

Threads in Java is one of the most important topic, which any Java Programmer should know. But how many of us actually know about it? or I would restate it – How many of us actually understand it deeply so that we won’t forget it for lifetime. I guess very few. So let’s start with basics and try to grasp the basics with deep understanding.

Thread – Basically there are two meanings of the word thread. One, its just a class called Thread (fully qualified class name is java.lang.Thread), which when instantiated gives an instance variable of Thread class. Second, the instance given if is started, becomes a “Thread of Execution”, which is very special for multi-threading.

Let’s see whats the difference between these two meanings of thread:

  1. Thread’s Instance:
    • Instance when initialized, starts living into the heap memory.
    • Instance has its own variables and methods.
  2. Thread of Execution:
    • “Thread of Execution” when comes into action, gets its own stack.
    • It works parallel to the Main thread. And when we say “Main thread” that’s the thread which is used to start the program, and it then creates other threads.
    • JVM(Java Virtual Machine) exits only when all the threads finishes there work.

Now we have understanding of thread, we can talk a little more practical. Thread (java.lang.Thread) class provides us a method run() which contains the code that you want to run in “Thread of execution”, and to run it we use another special method start() which on getting called, implicitly creates a Thread of execution and runs the code defined in run() method.

It might be a little bit confusing, but with following text it will make more sense.

    public void run() {
        System.out.println("Bike is running");

The run method is defined inside  a class called ThreadBike.

    ThreadBike bike = new ThreadBike();

The instance of ThreadBike is created and a start() method is called on it so that a new “Thread of Execution” starts and it executes the code inside run() method.

There are two different ways of defining and instantiating a thread.

  1. By implementing the interface Runnable.
  2. By extending the class java.lang.Thread,  which has already implemented the interface Runnable.

How to decide that which of these two should be used? Well, there is no hard and fast rule for that. But implementing Runnable is better as per Object Oriented practices. When we extend a class, we create a child version or specialized version of the parent class (Vehicle -> Bike, Vehicle -> Car). Extending a Thread would create a specialized class of it. But we are not creating a specialized class of Thread. We just want to create a job which is executed using a Thread, and implementing Runnable is the way to do that.

We will now see the both ways to define a Thread.

Defining a Thread by Extending the Thread class:

We have to define a thread by extending the Thread class and then override the run() method. The code for the job which we want to perform on the Thread, needs to be written inside the run() method. And then the instance of same class is used to call start() method as shown above.

public class ThreadBike extends Thread {
    public void run() {
        System.out.println("Bike is running");

If we don’t override the run() method, it will call the run() method of the Thread class on calling start() on this class’s instance.

Limitation in this method are as follows:

  • Its a poor design as per the Object Oriented concepts.
  • Above class cannot extend any other class.

Defining a Thread by Implementing a Runnable interface:

We can also define a thread by creating a job class which implements Runnable and then passing that class result into a Thread class instance and calling start() method.

public class ThreadCar implements Runnable{
    public void run() {
        System.out.println("Car is running");

The ThreadCar will be instantiated and passed to Thread class constructor as an argument.

ThreadCar car = new ThreadCar();
Thread thread =  new Thread(car);

Here car is the job and thread is the worker which will do the job.

The class which implements the Runnable interface has to override the run() method, which will get called on calling start() method on Thread class’s instance. Also in this case we have an advantage of passing same job to multiple Threads instances so that we can launch similar jobs on multiple threads, which is not possible in earlier case as we have only one Thread instance.

Some conceptual knowledge:

  • Can we overload run() method? Yes we can, but it won’t give us any advantage, as calling the start() method won’t create a new “Thread of Execution” using overloaded run() method.
  • The “Thread of Execution”  will be just be created from run() method which takes no input parameters, return type is void and access modifier is public.
  • The overloaded run() method can be called as a normal method by any piece of code, but it would be in same stack from where its called (Always remember new thread means new stack).
public class ThreadBike extends Thread {
    public void run() {                          //overridden method,
        System.out.println("Bike is running");   //Thread of Execution calls
    }                                            //this method
public void run(String str) {
        System.out.println("Bike is not running"); //overloaded method

One weird but conceptually true fact:

We can pass one Thread instance to another  Thread too as an argument. But its not the right way to program.

Thread thread = new Thread(new MyThread()); //MyThread implements Runnable

Done with this, now read about Nuances of Instantiating and Starting a Thread.

Hope you like it. Just comment to let us know what you think or ask questions if you have any. 🙂

Related Posts

One thought on “Java Threads – Do you know the basics?

Leave a Reply

Your email address will not be published.