Posted in Better Programming, Java Programming, Software Engineering

Basics of Java Threads

What is a thread?

A Thread in Java is a unit of execution within a process. Every Java program has atleast one thread (the main() thread). If we do not create a thread explicitly, our program runs on the main thread.

A process can therefore contain multiple threads. For this reason, creating threads is a more lightweight action compared to the resources it takes for the creation of a process. Threads terminate quickly as well compared to processes.

Why to use Multithreading?

  • To execute two or more threads at the same time and take advantage of multicore architectures
  • To run async background tasks such as logging, IO tasks etc
  • Run isolated code in parallel to increase computation speed for CPU bound processes
  • To create watchers for configuration changes

How to create threads?

Let’s look at some common ways of creating Threads in Java. There are a couple of simple ways to create threads in Java, namely

  • Implement the java.lang.Runnable interface and override the run() method
  • Extend the java.lang.Thread class and override the run() method


Method 1: Extend the java.lang.Thread class and override the run() method

public class Main {
    System.out.println("Running in main thread.");
    Thread myThread = new MyThread();
    myThread.setName("--- MyThread ---");
    myThread.start(); // This runs the thread
}

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Hello from " + currentThread().getName());

        try {
            Thread.sleep(2000); 
        } catch (InterruptedException e) {
            System.out.println("MyThread was interrupted.");
            return;
        }
    }       
}
Running in main thread.
Hello from --- MyThread ---

Method 2: Implement the java.lang.Runnable interface and override the run() method

In this method, we create an instance of the class implementing the Runnable interface and pass it to the Thread() constructor.

public class Main {

    public static void main(String[] args) {
        System.out.println("Running in main thread.");
        Thread myRunnableThread = new Thread(new MyRunnable());
        myRunnableThread.start();
    }
}

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("Hello from MyRunnable's run() method");
    }
}
Running in main thread.
Hello from MyRunnable's run() method

Method 3: Anonymous class overriding the run() method

public class Main {

    public static void main(String[] args) {
        System.out.println("Running in main thread.");

        new Thread() {
            @Override
            public void run() {
                System.out.println("Hello from the anonymous class run() method.");
            }
        }.start();
    }
}
Running in main thread.
Hello from the anonymous class run() method.

Method 4: Anonymous implementation of Runnable interface

public class Main {

    public static void main(String[] args) {
        System.out.println("Running in main thread.");

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello from the anonymous Runnable implementation of run() method");
            }
        }).start();
    }
}
Running in main thread.
Hello from the anonymous Runnable implementation of run() method

Gotchas

  • Every thread created in a process shares the process memory and files which can lead to concurrency problems if not handled correctly. Each Thread has its own Thread stack that only that particular thread can access.
  • A thread does not have to complete before another one starts unless we use something such as join() or interrupt() in Java or other ways to make a thread wait until another one completes execution. JVM decides when to schedule different threads to run.

Hope you learnt about the basics of Threads and some simplest ways of creating threads.

In the four methods that we saw above, threads should be instantiated and managed by developers manually. Oracle came up with a way of abstracting thread management using Executor API with its focus mainly on asynchronous processing rather than Thread management. This is a topic on its own, so let’s explore that in more detail in the next article along with synchronization of threads etc.

Unknown's avatar

Author:

I am a Backend Software Engineer working on Search and Ranking Infrastructure Technologies at Yelp Inc in Bay Area, California. I have a masters in Electrical and Computer Science Engineering from University of Washington, Seattle. I have been working on AI, Machine Learning, Backend Infrastructure and Search Relevance over the past several years. My website: www.thatgirlcoder.com https://www.linkedin.com/in/swethakn/

One thought on “Basics of Java Threads

Leave a reply to Alex Cancel reply