In Java multithreading, two commonly discussed methods are start()
and run()
. At first glance, they may look similar—after all, both are related to starting a thread—but they function in very different ways.
If you’re learning Java or preparing for interviews, it’s crucial to understand the key differences between start()
and run()
, how they work, when to use them, and what happens behind the scenes.
In this article, we’ll explore these two methods using clear explanations, practical code examples, and a comparison table.
Introduction to Multithreading in Java
Java supports multithreading, allowing concurrent execution of two or more parts of a program for maximum utilization of CPU. To implement multithreading, Java provides the Thread
class and the Runnable
interface.
start()
andrun()
are central to this threading mechanism.- But confusing them can lead to incorrect program behavior.
What is start()
in Java?
The start()
method is a member of the java.lang.Thread
class. It is used to create a new thread of execution and begin the execution of the code written in the run()
method.
When you call start()
on a thread object:
- A new thread is created by the JVM.
- That thread executes the
run()
method asynchronously.
Example:
class MyThread extends Thread {
public void run() {
System.out.println("Running in: " + Thread.currentThread().getName());
}
}
public class StartDemo {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // creates a new thread
}
}
Output:
Running in: Thread-0
What is run()
in Java?
The run()
method is defined in the Runnable
interface. It contains the actual code that you want the thread to execute.
However, if you call run()
directly like a regular method, no new thread is created—the code executes in the current thread.
Example:
class MyThread extends Thread {
public void run() {
System.out.println("Running in: " + Thread.currentThread().getName());
}
}
public class RunDemo {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.run(); // no new thread, just a method call
}
}
Output:
Running in: main
📊 start()
vs run()
– Comparison Table

Example: Difference in Execution Threads
class Demo extends Thread {
public void run() {
System.out.println("Executed by: " + Thread.currentThread().getName());
}
}
public class StartVsRun {
public static void main(String[] args) {
Demo t1 = new Demo();
Demo t2 = new Demo();
// Calling run() directly
t1.run(); // Runs in main thread
t2.run(); // Runs in main thread
// Calling start()
t1.start(); // Runs in a new thread
t2.start(); // Runs in another new thread
}
}
Output:
Executed by: main
Executed by: main
Executed by: Thread-0
Executed by: Thread-1
This clearly shows the difference — run() keeps execution in the main thread, while start() creates new threads.
Why You Should Never Call run()
Directly
Many beginners assume that calling run()
will start a new thread. But that's not true.
Thread t = new Thread(() -> System.out.println("Task"));
t.run(); // ❌ Wrong: no new thread
t.start(); // ✅ Correct: starts new thread
Calling run()
like a regular method defeats the whole purpose of multithreading. It's just a normal method call.
❌ What Happens if You Call start()
Twice?
Once a thread has been started, calling start()
again will throw an IllegalThreadStateException.
⚠️ Example:
Thread t = new Thread(() -> System.out.println("Hello"));
t.start();
t.start(); // ❌ Throws exception
Output:
Hello
Exception in thread "main" java.lang.IllegalThreadStateException
You must create a new Thread object to start the thread again.
🔁 When Should You Use run()
?
Although run()
doesn’t create new threads on its own, it still plays a valuable role:
- You override it to define the logic that a thread should execute.
- You can also use it like a helper method when you don’t need threading.
Runnable r = () -> System.out.println("Running task");
r.run(); // Just executes the logic like a regular method
🔁 When Should You Use start()
?
Always use start()
when:
- You want to run a task asynchronously.
- You want true parallelism or concurrent execution.
- You’re dealing with CPU-bound or I/O-bound tasks that can benefit from multithreading.
Runnable r = () -> System.out.println(Thread.currentThread().getName());
Thread t = new Thread(r);
t.start(); // Executes in a new thread
🧾 Real-World Use Case
Let’s simulate a real-world scenario: a file download operation.
class FileDownloader extends Thread {
public void run() {
System.out.println("Downloading file by " + Thread.currentThread().getName());
}
}
public class DownloaderApp {
public static void main(String[] args) {
FileDownloader task1 = new FileDownloader();
FileDownloader task2 = new FileDownloader();
task1.start(); // Downloads in parallel
task2.start();
}
}
- Both downloads happen in parallel threads, keeping the application responsive.
Final Thoughts
- Use
start()
when you want true multithreading. - Use
run()
to define what the thread should execute. - Calling
run()
directly means you're not using threads at all. - Never call
start()
more than once on the same thread object.
By understanding these differences and following best practices, you’ll be better equipped to write efficient, multi-threaded Java applications.
Comments
Post a Comment
Leave Comment