Starting a thread

Read the explanation
What if

start() runs download() on a new thread, and main carries on at once. The JVM waits for worker before it exits.

012345678main: new Thread(…)newstart()printlndownload()

Tap any block to see what that thread is doing.

  • Running
  • Waiting on I/O
Step 1/5

new Thread(…) only creates an object. Nothing runs yet: worker is NEW.

1Thread worker = new Thread(() -> download(), "worker");2worker.start();                     // a new thread runs download()3System.out.println("main goes on"); // main doesn't wait4// main ends here; the JVM waits for worker

Explanation

What just happened

new Thread(...) only built an object. start() asked the operating system for a real thread, and that thread ran download() while main kept going. main finished first, but the program didn’t end: the JVM waited for worker.

Try the what-if switch

The rule

Call Runs on main waits?
start() the new thread no
run() the caller yes, it’s a plain call

The JVM exits when the last non-daemon thread ends. Daemons are for background helpers whose work can be thrown away, like a cache cleaner.

In real code

You rarely create threads by hand. An ExecutorService reuses a few threads for many tasks, and the next scenarios use one. But every executor does exactly this underneath: it calls start() once per thread, then feeds it tasks.

Common questions

What is the difference between start() and run() in Java?

start() runs your code on a new thread and returns at once. run() is a plain method call: the code runs on the calling thread, nothing runs in parallel, and the thread stays NEW.

Can I call start() twice on the same thread?

No. A second start() throws IllegalThreadStateException, even after the thread has finished. Create a new Thread, or use an executor.

Does the JVM wait for daemon threads before it exits?

No. The JVM exits when the last non-daemon thread ends, and daemon threads are stopped wherever they are. Mark a thread with setDaemon(true) before calling start().

Verified: this timeline matches a real program, checked in CI on JDK 21 and 25. How we verify. Unclear or wrong? Tell us