Multithreading
A thread is an independent flow within a program. Normally, Java runs in a single thread (main).
You can create new threads by extending Thread or implementing Runnable, which then do work in parallel.
class MyThread extends Thread {
public void run() { System.out.println("Running..."); }
}
new MyThread().start();Thread class extend karo aur run() override karo — simple hai lekin ye "extends" slot use kar leta hai (Java single inheritance hai, isliye tumhari class ab kuch aur extend nahi kar sakti).
Ya Runnable interface implement karo aur usse Thread ko pass karo — ye better practice hai kyunki class doosri bhi extend kar sakti hai, aur behavior (Runnable — "kya karna hai") thread (Thread — "kaise chalana hai") se alag rehta hai. Modern Java mein Runnable approach hi zyada recommend hoti hai.
| extends Thread | implements Runnable | |
|---|---|---|
| Doosri class extend kar sakte ho? | Nahi | Haan |
| Recommended? | Kam | Zyada (best practice) |
| ExecutorService ke saath use | Mushkil | Aasan |
class MyTask implements Runnable {
public void run() { System.out.println("Running!"); }
}
Thread t = new Thread(new MyTask());
t.start();Har thread ki priority hoti hai (1 se 10, default 5, setPriority() se change kar sakte ho) — JVM ko ek "hint" deta hai kis thread ko zyada CPU time milna chahiye (guarantee nahi hai, OS-dependent, kai OS is hint ko ignore bhi kar sakte hain).
Daemon thread background service threads hote hain (jaise Garbage Collector khud ek daemon thread hai) — jab saare non-daemon (normal) threads khatam ho jaate hain, JVM daemon threads ki parwaah kiye bina exit ho jaata hai. setDaemon(true) se koi thread ko daemon banaya ja sakta hai (start() se pehle call karna zaroori hai).
Thread.sleep(ms) current thread ko kuch der ke liye "pause" kar deta hai — koi doosra thread ka wait nahi kar raha, bas apna time pass kar raha hai (ye static method hai, current thread par hi asar karta hai).
t.join() ek thread ko doosre thread (t) ke *khatam hone tak* wait karwata hai — jaise main thread chahta ho ki worker thread pehle apna kaam poora kare, tab hi aage badhe. Ye tab useful hai jab result ek thread se doosre thread ko chahiye.
Thread worker = new Thread(() -> doWork());
worker.start();
worker.join(); // main thread yaha wait karega worker khatam hone tak
System.out.println("Worker done, ab aage badho");Jab multiple threads ek shared variable ko simultaneously change karne ki koshish karte hain bina proper synchronization ke, result unpredictable ho jaata hai — isko "race condition" kehte hain.
Jaise do threads ek counter ko ++ kar rahe hon: count++ actually 3 steps hain (read current value, add 1, write back) — agar dono threads ek saath "read" kar lein purani value, dono apna-apna increment likhenge, lekin ek update "lost" ho jaayega (final value expected se kam aayegi).
// DANGEROUS without synchronization:
class Counter {
int count = 0;
void increment() { count++; } // NOT atomic! race condition risk
}