为何使用Runnable接口?为何需实现run()而非直接调用start()启动进程?
Great question—this cuts right to the core of how Java’s threading model is designed, so let’s break down each part of your query step by step.
1. Why even use the Runnable interface at all?
The biggest reason ties to Java’s single inheritance limit. If you create a thread by extending the Thread class, you can’t extend any other class in your code. But since Runnable is an interface, you can implement it alongside other classes, keeping your code flexible and following the "composition over inheritance" best practice.
Another key win is decoupling task logic from thread management. The Runnable interface exists purely to define the work your thread should do, while the Thread class handles the low-level heavy lifting: creating a new execution thread, scheduling it with the OS, and managing its lifecycle. This means you can reuse the same Runnable task across multiple threads, or even run it in a thread pool later without rewriting core logic.
2. If Runnable has no connection to start(), why use it?
Actually, they are connected—just indirectly. Here’s the breakdown:
- The
Threadclass itself implementsRunnable, and itsstart()method is the magic that tells the JVM to spin up a new native thread. - When you pass a
Runnableinstance to aThreadconstructor, theThread’s ownrun()method will call your customRunnable’srun()method once the new thread is ready. - So while
Runnabledoesn’t have astart()method, it’s the bridge between your task logic and theThreadclass that actually launches the thread. Without it, you’d have to overrideThread’srun()method directly, which ties your task tightly to the thread itself (terrible for reuse).
3. Why can’t I just write a run() method and call it directly?
Because calling run() directly is just a regular method call—it won’t create a new thread. Let’s use a concrete example:
class MyTask { public void run() { System.out.println("Doing work..."); } } // This runs in the CURRENT thread—no new thread is created! MyTask task = new MyTask(); task.run();
The start() method is special: it triggers the JVM to allocate a separate thread of execution, and then calls run() on that new thread. That’s the whole point of multi-threading—parallel execution. Calling run() directly skips the thread creation step entirely.
4. Why do I have to implement run() instead of just using it with start()?
Because Runnable is a functional interface that defines a clear contract: "here’s the code that should run in a thread". The Thread class needs this contract to know exactly what code to execute when the thread starts.
If you don’t implement Runnable (or override Thread’s run()), the default run() method in Thread does nothing. Think of it like this: start() is the button that starts the thread engine, but run() is the fuel—the actual work you want the engine to do. You have to provide that fuel by implementing run().
Plus, using Runnable keeps your code modular. You can swap out different Runnable implementations without changing the code that manages the thread, which is a clean separation of concerns.
内容的提问来源于stack exchange,提问作者Vignesh

