Java’s threading model can trip up even experienced developers. One of the most common sources of confusion? The difference between t.start()
and t.run()
.
If you’ve ever written a multithreaded program in Java, you’ve likely encountered both. But what actually happens when you call t.start()
instead of t.run()
— and why does it matter?
Quick Answer: t.start()
vs t.run()
t.start()
: Starts a new thread and executes therun()
method in that new thread.t.run()
: Calls therun()
method in the current thread, just like a normal method.
Sounds simple, right? But the consequences are huge.
Let’s break it down with code examples and real-world implications.
A Little Threading Background
Java supports multithreading — the ability to run multiple threads (independent units of work) simultaneously. You can create threads by:
- Extending the
Thread
class. - Implementing the
Runnable
interface.
In both cases, you override the run()
method, which holds the code you want the thread to execute.
But here’s the twist: overriding run()
doesn’t actually start the thread. That’s what start()
is for.
t.start()
vs t.run()
in Action
public class Demo extends Thread {
public void run() {
System.out.println("Running in: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
Demo t1 = new Demo();
System.out.println("Calling t1.run()");
t1.run(); // Executes in main thread
System.out.println("Calling t1.start()");
t1.start(); // Executes in new thread
}
}
Output:
Calling t1.run()
Running in: main
Calling t1.start()
Running in: Thread-0
What’s Happening Here?
t1.run()
runs just like any regular method — in the main thread.t1.start()
creates a new thread and callsrun()
in that thread.
That’s the real difference between t.start()
vs t.run()
.
Why It Matters: Real-World Implications
1. Concurrency
Using t.start()
enables true parallel execution. Your app can do multiple things at once.
Using t.run()
? Everything runs sequentially in the same thread. No concurrency. Just like calling any other method.
2. Performance
On multi-core processors, t.start()
lets Java take full advantage of your CPU. Each thread can run independently.
t.run()
? No benefit — it runs synchronously, blocking other operations.
3. Thread Behavior
start()
sets up everything: thread stack, scheduling, life cycle management.
run()
bypasses that. You’re not creating a new thread; you’re just executing some code.
Common Mistakes to Avoid
Mistake 1: Using t.run()
and expecting multithreading
Thread t = new Thread(() -> {
System.out.println("Running in: " + Thread.currentThread().getName());
});
t.run(); // Looks like threading, but isn't!
You just called a method. No new thread is created. Use t.start()
instead.
Mistake 2: Calling start()
twice
Thread t = new Thread(() -> {
System.out.println("Hello!");
});
t.start(); // OK
t.start(); // IllegalThreadStateException
Once a thread has been started, it can’t be restarted. You’ll get a runtime exception if you try.
Practical Tip: Always Use start()
for Threads
If your goal is concurrency, always use start()
. The only time you’d use run()
directly is for testing or if you’re intentionally avoiding multithreading (rare).
Loop with Threads
for (int i = 0; i < 3; i++) {
Thread t = new Thread(() -> {
System.out.println("Running in: " + Thread.currentThread().getName());
});
t.start(); // Right choice
}
Want concurrency? Use start()
— always.
t.start() vs t.run()
in Java
When comparing t.start() vs t.run()
, the key takeaway is this:
start()
kicks off a new thread.run()
just runs the code in the current thread.
If you want real multithreading, go with t.start()
. If you call t.run()
, you’re just calling a method — no thread magic involved.
This difference is critical when building responsive, scalable Java applications — whether it’s for a web server, a game engine, or a background worker.
Key Takeaways
t.start()
creates a new thread and callsrun()
in it.t.run()
runs like a normal method — no new thread.- Always use
start()
to actually start threading. - Don’t call
start()
more than once on the same thread. - If it runs in the main thread, it’s not really multithreaded.
Conclusion
Understanding t.start() vs t.run()
is foundational for writing efficient, concurrent Java programs. It’s not just about syntax — it’s about how your code executes in real time.
So next time you see run()
, stop and ask: Am I actually starting a thread, or just calling a method?
If you want true multithreading, start()
is your ticket.