Theory
5 pm पर Desk Freeze हो जाती है
New BookBridge feature: closing time पर, सारे issued books scan करना और अपनी due date के करीब किसी भी चीज़ के लिए reminders print करना। 6000 records, लगभग 40 seconds।
Problem: जब तक वह scan चलता है, return desk frozen है। Program busy है, librarian click करती है, कुछ respond नहीं करता, एक queue बन जाती है।
Scan को desk की ज़रूरत नहीं है; वे बस same program में रहते हैं, execution के एक path पर turns लेते हुए। हमें जो चाहिए वह एक second path है। Java इसे thread कहता है।
Theory
दो Assistants, एक Library
अब तक आपने जो हर program लिखा है वह एक assistant वाली एक library है जो sequence में सब कुछ करता है: एक member serve करो, फिर reminders check करो, फिर register update करो।
एक thread same library के अंदर एक दूसरा assistant hire करता है: same shelves, same records (same objects और memory), simultaneously काम करते हुए। एक desk serve करता है, दूसरा quietly shelves walk करके reminder list बनाता है। Building walk खत्म होने का wait नहीं करती।
Theory
Thread और इसकी Life, Formally
एक thread एक program के अंदर execution का एक independent path है। हर Java program के पास पहले से एक है: JVM main thread पर main run करता है; आप और बनाते हैं।
Thread model वह life cycle है जिसे हर thread walk करता है:
- New: created, start() अभी call नहीं हुआ
- Runnable: ready, scheduler की turn का wait
- Running: currently CPU पर execute हो रहा
- Blocked/Waiting: एक resource, sleep या दूसरे thread के लिए paused
- Dead: run() खत्म; एक dead thread restart नहीं हो सकता
Practical
Reminder को अपना Assistant मिलता है
class Reminder implements Runnable { // sign the contract
public void run() { // the thread's task lives here
for (int i = 1; i <= 3; i++) {
System.out.println("Reminder check " + i);
}
}
}
public class BookBridge {
public static void main(String[] args) {
Thread t = new Thread(new Reminder());
t.setPriority(Thread.MAX_PRIORITY); // 10: a hint, not an order
t.start(); // birth of the second path
System.out.println("Desk keeps serving");
}
}
Theory
अंदर आने के दो तरीके, एक Clear Winner
Java 2 creation routes offer करता है:
- extends Thread: आपकी class एक thread HAI; run() override कीजिए, start() call कीजिए
- implements Runnable: आपकी class के पास एक task HAI; इसे
new Thread(task)को हैंड कीजिए
Runnable prefer कीजिए, और exam में क्यों बताइए: Java classes को एक extends slot मिलता है (single inheritance)। Reminder को कभी किसी और class को extend करना पड़ सकता है; Runnable implement करना वह slot free रखता है। यह task (क्या करना है) को machinery (Thread जो इसे run करता है) से भी separate करता है, और यह पिछली unit का interface pattern है living के लिए काम करते हुए।
Quiz
एक student t.start() के बजाय t.run() लिखता है। Program काम करता है, तो असल में क्या बदला?
- कुछ नहीं; run() और start() synonyms हैं
- कोई नया thread create नहीं हुआ: run() current thread पर एक ordinary method call की तरह execute हुआ
- Thread run हुआ, पर minimum priority पर
- Compile error: run() directly call नहीं हो सकता
Show the answer
कोई नया thread create नहीं हुआ: run() current thread पर एक ordinary method call की तरह execute हुआ
start() magic step है: यह JVM से genuinely एक नया execution path create करने को कहता है, जो फिर उस नए thread पर run() call करता है। खुद run() call कीजिए और यह बस एक normal method call है: reminder loop MAIN thread पर run होता है, sequentially, desk फिर से frozen, exactly वह problem जिसे solve करने हम आए थे। Output identical दिख सकता है, यही वजह है यह bug testing survive करता है। Options C और D behaviour invent करते हैं: priority untouched है और call perfectly legal है, बस ग़लत।
Think first
कौन पहले Print करता है?
Listing में, reminder thread के पास MAX_PRIORITY है। Tap करने से पहले: क्या "Reminder check 1" "Desk keeps serving" से पहले appear होना guaranteed है?
Show the answer
No. Priority (MIN_PRIORITY 1, NORM_PRIORITY 5, MAX_PRIORITY 10) thread scheduler के लिए एक suggestion है, एक command नहीं; scheduler और operating system अभी भी decide करते हैं कौन कब run होता है। main शायद अपनी line new thread को अपनी पहली turn मिलने से पहले print कर दे, और same program के 2 runs अलग तरीके से interleave हो सकते हैं। Exam sentence: thread priority scheduling को influence करता है पर कुछ भी guarantee नहीं करता। कभी program correctness priorities पर build मत कीजिए।
Watch out
तीन Thread Traps
start() के बजाय run(): कोई नया thread नहीं, silently sequential: ऊपर वाला quiz, और #1 practical bug।
एक Dead Thread Restart करना: एक बार run() complete हो जाए, फिर से start() call करना IllegalThreadStateException throw करता है; इसके बजाय एक नया Thread object बनाइए।
Output Order पर Trust करना: कोई भी answer जो 2 running threads के एक fixed interleaving का claim करता है ग़लत है; "order unpredictable है" लिखिए और आप precise होंगे।
Theory
Threads जिनसे आप पहले ही मिल चुके हैं
BCA305-02 का हर Android app अपनी screens एक main thread पर run करता है (इसे freeze कीजिए और OS "app not responding" दिखाता है, वही 5 pm desk problem)। पिछली unit के StringBuffer के synchronized methods exactly इसीलिए exist करते हैं क्योंकि 2 threads एक buffer edit कर सकते हैं। और आज की listing का Runnable Unit 2 का interface contract है, signed और अपनी keep earn करते हुए। अगला lesson zoom out करता है: BookBridge के बढ़ते classes के ढेर को packages में organise करना।
Summary
Key takeaways
- एक thread एक program के अंदर execution का एक independent path है; main main thread पर run होता है।
- Life cycle: new, runnable, running, blocked/waiting, dead; dead threads कभी restart नहीं होते।
- extends Thread या (preferred) implements Runnable + new Thread(task) से create कीजिए: extends slot free रखता है।
- start() नया thread birth देता है जो run() call करता है; run() को directly call करना बस current thread पर एक method call है।
- Priorities: 1 (MIN), 5 (NORM), 10 (MAX), setPriority() से set किए गए: scheduler के लिए hints, कभी guarantees नहीं।
- Running threads के बीच output order unpredictable है; exams में यही कहिए।
- Memory hook: start() assistant hire करता है, run() बस आप खुद काम कर रहे हैं।