1. Using Threads
1 | public static void main(String[] args) { |
Both threads ran their run() method. Here’s the output:
1 | Running thread 1 |
Both threads ran, but thread 1 was started via start() while thread 2 was invoked by calling run() directly.
2. The Difference Between start() and run()
To see the exact difference, we need to print thread information:
1 | public static void main(String[] args) { |
Output:
1 | Running thread 1; thread name: Thread-0 |
The output tells the story clearly: start() spawns a new thread to execute run(), while calling run() directly executes it on the main thread, just like any ordinary method call.
We can take this further by calling run() multiple times on the same thread:
1 | public static void main(String[] args) { |
Output:
1 | Running thread 1; thread name: main |
The results speak for themselves: run() can be called repeatedly, but start() can only be called once. Here’s why, from the start() method source:
1 | public synchronized void start() { |
When start() is called, it first checks whether the thread’s status is 0 (NEW). If not, it throws an exception. On the first start() call, the thread transitions from NEW to RUNNABLE. By the time you call start() a second time, the status is no longer NEW, so the exception fires.
3. Summary
Both start() and run() get the job done, but they differ in three key ways:
- Execution model: calling
run()directly is just a regular method call on the current thread; callingstart()creates a new thread and runsrun()on it. - Timing:
run()executes immediately on the calling thread;start()sets the thread to RUNNABLE state and waits for CPU scheduling, so it doesn’t run right away. - Invocation limit:
run()can be called repeatedly, butstart()is strictly one-shot.