Java threads — creating and starting threads
Thread class, Runnable interface, lambda threads, thread lifecycle, start vs run, thread name, daemon threads, Thread.sleep, join method
Creating Threads
A thread is an independent path of execution within a program. Java threads map to OS threads and run concurrently on available CPU cores, enabling parallelism and responsive applications.
Three Ways to Create a Thread
// 1. Extend Thread
class PrintThread extends Thread {
@Override
public void run() { System.out.println("Thread: " + getName()); }
}
// 2. Implement Runnable
Runnable task = new Runnable() {
@Override
public void run() { System.out.println("Runnable task"); }
};
// 3. Lambda (preferred for simple tasks)
Runnable lambda = () -> System.out.println("Lambda thread");
Starting Threads
Thread t1 = new PrintThread();
Thread t2 = new Thread(lambda, "WorkerThread");
t1.start(); // new OS thread — calls run() concurrently
t2.start();
// WRONG: t1.run() — synchronous call, no new thread created
t1.join(); // current thread waits until t1 finishes
t2.join();
System.out.println("Both threads done");
Thread.sleep(1000); // pause current thread 1 second
Always call start(), never run() directly. Calling run() is just a regular method call on the current thread.
Daemon threads (setDaemon(true) before start()) die automatically when all non-daemon threads finish, making them suitable for background tasks like logging that should not block JVM shutdown. The main thread is non-daemon by default.
Use Thread.currentThread().interrupt() in catch blocks for InterruptedException to restore the interrupted status. Swallowing the interrupted flag silently prevents the calling code from knowing a shutdown was requested.
