There are 3 main ways to create a Thread:

Extending Thread Class
class MyThread extends Thread {
    public void run() {
        System.out.println("Running in MyThread");
    }
}
 
MyThread t1 = new MyThread();
t1.start(); // Always use start(), not run()
// Less flexible (can't extend other classes)
Implementing Runnable Interface - Recommended
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Running in Runnable");
    }
}
 
Thread t2 = new Thread(new MyRunnable());
t2.start();
// Better for reusability, preferred in modern Java
Using Callable + Future (With Executor)
Callable<String> task = () -> {
    return "Result from thread";
};
 
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(task);
 
String result = future.get(); // blocks until result is ready
executor.shutdown();
// Returns a result + Can throw checked exceptions

Comparison

run() vs start()

MethodWhat It Does
run()Runs code in the current thread
start()Starts a new thread, runs run() internally

Real-World Use

ApproachUse When…
ThreadQuick + simple threading, one-off usage
RunnableCommonly used in real apps & frameworks
CallableYou need a return value from the thread
ExecutorsManaging multiple threads efficiently

Tip

Be ready to:

  • write class using Runnable or Callable,
  • explain start() vs run(),
  • talk about when to use ExecutorService (thread pools)

Parent: _Multithreading