Show List

Java Multithreading Tutorial: Create and Manage Threads

Multithreading in Java enables a program to run multiple threads concurrently, maximizing CPU utilization and improving application responsiveness. Each thread acts as a lightweight sub-process within the Java Virtual Machine (JVM), allowing developers to perform tasks like I/O operations, computations, or background processing without blocking the main thread. This tutorial covers how to create threads using both the Thread class and the Runnable interface. It also dives into thread lifecycle states, priority management, and key thread-handling methods like start(), sleep(), and join(). By the end of this guide, you'll have a strong foundation to build robust, concurrent Java applications.

 There are two ways in which a Thread can be created:
  • Extending Thread Class
  • Implementing the Runnable Interface

Extending Thread Class

class ThreadDemo extends Thread {
private Thread t;
private String threadName;

//Constructor
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating Thread " + threadName );
}

//Override method from Thread class
public void run() {
System.out.println("Running Thread " + threadName );
try {
for(int i = 2; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);

// Make the thread sleep for a while.
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}

//Override method from Thread class
public void start () {
System.out.println("Starting Thread " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start (); //Run method is called when the thread is started.
}
}
}

public class Demo {

public static void main(String args[]) {

//Creating the thread object
ThreadDemo T1 = new ThreadDemo( "One");
//Starting first thread
T1.start();

//Creating another thread object
ThreadDemo T2 = new ThreadDemo( "Two");
//Starting second thread
T2.start();
}
}
In the example above, ThreadDemo class extends Thread class. So an object created from this class would be a thread. Methods run and start are overridden to provide the custom behavior to the thread (In this case to print the messages).

Output:
Creating Thread One
Starting Thread One
Creating Thread Two
Starting Thread Two
Running Thread One
Running Thread Two
Thread: One, 2
Thread: Two, 2
Thread: One, 1
Thread: Two, 1
Thread One exiting.
Thread Two exiting.

Process finished with exit code 0

Implementing the Runnable Interface

class RunnableDemo implements Runnable {
//Instance variables
private Thread t;
private String threadName;

//Constructor
RunnableDemo( String name) {
threadName = name;
System.out.println("Creating Thread " + threadName );
}

//Implement method from Runnable interface
public void run() {
System.out.println("Running Thread " + threadName );
try {
for(int i = 2; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);

// Make the thread sleep for a while.
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}

public void start () {
System.out.println("Starting Thread " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();//Run method is called when the thread is started.
}
}
}

public class Demo {

public static void main(String args[]) {
//Creating the thread object
RunnableDemo T1 = new RunnableDemo( "One");
//Starting first thread
T1.start();

//Creating another thread object
RunnableDemo T2 = new RunnableDemo( "Two");
//Starting second thread
T2.start();
}
}

In this example the thread class RunnableDemo is created by implementing the Runnable interface. Method run is implemented to provide the custom behavior to the thread (In this case to print the messages).

Output:
Creating Thread One
Starting Thread One
Creating Thread Two
Starting Thread Two
Running Thread One
Thread: One, 2
Running Thread Two
Thread: Two, 2
Thread: One, 1
Thread: Two, 1
Thread One exiting.
Thread Two exiting.

Process finished with exit code 0

Thread States

Java thread can be in any of the following state:
  • New - When we create an instance of Thread class, a thread is in a new state
  • Runnable/Running - When the thread is started
  • Suspended - A thread can be suspended to pause the processing.
  • Waiting - When thread is waiting for another thread to perform a task.
  • Terminated - When execution is complete

Thread Priority

A priority can be assigned to threads based of the priority of task thread is to complete. setPriority() is the method to set priority and getPriority is the method to find the priority of a thread.
  • Priority can be between 1 to 10
  • 5 is default priority

Thread Methods

  • start() – Starts the thread.
  • getName() – It returns the name of the thread.
  • sleep(long millis) – Stop the thread for the specified time.
  • Join() – Stop the current thread until the called thread gets terminated.
  • isAlive() – Check if the thread is alive.
  • getState() – It returns the state of the thread.
  • getPriority() – It returns the priority of the thread.
  • interrupt() - Interrupts the thread

Java multithreading is a vital skill for any developer building scalable, responsive applications. Whether you're managing background tasks or executing operations in parallel, understanding how to work with Thread and Runnable, manage thread states, and use thread lifecycle methods effectively is essential. Continue exploring advanced concepts like synchronization and thread pools to take full control over concurrent programming in Java.

FAQs 

1. What is multithreading in Java?

Multithreading in Java allows concurrent execution of two or more threads for maximum CPU utilization and performance.

2. What are the two ways to create a thread in Java?

Threads in Java can be created by extending the Thread class or by implementing the Runnable interface.

3. Which is better: implementing Runnable or extending Thread?

Implementing Runnable is generally preferred as it promotes better object-oriented design and allows extending other classes.

4. What is the lifecycle of a Java thread?

The thread lifecycle includes states: New, Runnable, Waiting, Timed Waiting, and Terminated.

5. What does the sleep() method do in Java?

The sleep() method pauses a thread’s execution for a specified time, allowing other threads to run.

6. How do you start a thread in Java?

You start a thread by calling the start() method on a Thread object, which then invokes the run() method.

7. What happens if run() is called directly instead of start()?

Calling run() directly doesn’t create a new thread; it executes in the current thread like a normal method.

8. Can thread priority affect execution order?

Yes, thread priority may influence the scheduler, but it is not guaranteed—OS-specific thread scheduling applies.

9. How to stop a thread safely in Java?

You should design threads to check a volatile flag or use interrupt() and handle InterruptedException gracefully.


    Leave a Comment


  • captcha text