🏃‍♂️
Multithreading

Multithreading

Doing Many Things at Once
💡 Single thread एक अकेला runner है जो एक-एक करके सब काम करता है। Multithreading कई runners एक साथ अलग-अलग tracks पर दौड़ते हैं — काम जल्दी होता है!

Thread program का एक independent flow है। Normally Java एक thread (main) में चलता है।

Thread class extend करके या Runnable implement करके नए threads बना सकते हो, जो parallel काम करते हैं।

class MyThread extends Thread {
  public void run() { System.out.println("Running..."); }
}
new MyThread().start();
🏃‍♂️
Single thread एक अकेला runner है जो एक-एक करके सब काम करता है। Multithreading कई runners एक साथ अलग-अलग tracks पर दौड़ते हैं — काम जल्दी होता है!
1 / 3
इस page में (4 subtopics)

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 Threadimplements Runnable
Doosri class extend kar sakte ho?NahiHaan
Recommended?KamZyada (best practice)
ExecutorService ke saath useMushkilAasan
class MyTask implements Runnable {
  public void run() { System.out.println("Running!"); }
}
Thread t = new Thread(new MyTask());
t.start();
⚠️Common Mistake: t.run() call karna aur t.start() call karna bilkul alag hai! run() sirf ek normal method call hai (same thread mein chalega, koi naya thread nahi banega). start() hi actually naya thread banata hai jo parallel mein run() ko execute karta hai.

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
}
⚠️Common Mistake: count++ ek single, atomic operation NAHI hai — ye read-modify-write hai. Multi-threaded environment mein isse race condition ho sakti hai. Fix ke liye synchronized ya AtomicInteger use karo (agla topic mein detail).