जावा में कंकरेंसी: क्लासिकल थ्रेड्स से गोरूटीन्स और async/await तक
\n\nजावा एक ऐसी भाषा है जो जन्म से ही एक साथ कई कार्यों को संभालने में सक्षम है। लेकिन दुनिया स्थिर नहीं है। आज हम जावा में कंकरेंसी के बारे में बात करेंगे — पुराने अच्छे थ्रेड्स (Thread) से लेकर वर्चुअल थ्रेड्स (Project Loom से गोरूटीन्स) और async/await के साथ एसिंक्रोनस दृष्टिकोण (CompletableFuture के उदाहरण के साथ) तक।
\n\nयदि आप जावा में कोड लिखते हैं और चाहते हैं कि आपका सर्वर लोड के तहत "धीमा" न हो, और कोड पढ़ने योग्य बना रहे, — तो यह लेख आपके लिए है। चलिए शुरू करते हैं!
\n\nआधुनिक जावा डेवलपर के लिए कंकरेंसी क्यों महत्वपूर्ण है?
\n\nकल्पना करें कि आपकी वेबसाइट प्रति सेकंड 10,000 अनुरोधों को संसाधित करती है। यदि प्रत्येक अनुरोध क्रमिक रूप से निष्पादित होता है, तो उपयोगकर्ता अनंत काल तक प्रतीक्षा करेंगे। जावा में कंकरेंसी प्रोसेसर संसाधनों का कुशलतापूर्वक उपयोग करते हुए कई कार्यों को "एक साथ" निष्पादित करने की अनुमति देता है।
\n\nआधुनिक एप्लिकेशन केवल CRUD नहीं हैं। ये माइक्रोसर्विसेज, डेटा स्ट्रीम प्रोसेसिंग, WebSocket, रीयल-टाइम एनालिटिक्स हैं। जावा मल्टीथ्रेडिंग की समझ के बिना, आप ऐसा कोड लिखने का जोखिम उठाते हैं जो या तो OutOfMemoryError के साथ क्रैश हो जाएगा या घोंघे की गति से काम करेगा।
\n\nस्तर 1: क्लासिकल थ्रेड्स (Thread) — नींव
\n\nजावा में थ्रेड कोड को समानांतर रूप से निष्पादित करने के लिए सबसे निम्न-स्तरीय एब्स्ट्रैक्शन है। प्रत्येक थ्रेड ऑपरेटिंग सिस्टम के अंदर एक अलग "हल्का" प्रक्रिया है।
\n\nथ्रेड बनाने का सबसे सरल उदाहरण इस प्रकार है:
\n\npublic class ThreadExample {\n public static void main(String[] args) {\n Thread thread = new Thread(() -> {\n for (int i = 0; i < 5; i++) {\n System.out.println("थ्रेड से नमस्ते: " + i);\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n Thread.currentThread().interrupt();\n }\n }\n });\n thread.start();\n System.out.println("मुख्य थ्रेड काम करता रहता है");\n }\n}\n\nलाभ:
\n- \n
- सृजन में सरलता — new Thread(() -> { ... }).start(); \n
- जीवनचक्र का सीधा प्रबंधन। \n
नुकसान:
\n- \n
- थ्रेड बनाना एक महंगी प्रक्रिया है (स्टैक, कॉन्टेक्स्ट स्विचिंग पर ओवरहेड)। \n
- संख्या में सीमा: 10,000 थ्रेड आपकी JVM को मार सकते हैं। \n
- सिंक्रनाइज़ेशन की जटिलता: डेडलॉक, रेस कंडीशन। \n
क्लासिकल दृष्टिकोण छोटे कार्यों के लिए अच्छा है, लेकिन हाई-लोड एप्लिकेशन के लिए उपयुक्त नहीं है। यहीं पर जावा में वर्चुअल थ्रेड्स मदद के लिए आते हैं।
\n\nस्तर 2: वर्चुअल थ्रेड्स (Project Loom) — जावा में गोरूटीन्स
\n\nयदि आपने Go में गोरूटीन्स के बारे में सुना है, तो जावा वर्चुअल थ्रेड्स लगभग वैसे ही हैं। वे Java 21 (Project Loom) में दिखाई दिए और खेल के नियमों को पूरी तरह से बदल देते हैं।
\n\nवर्चुअल थ्रेड्स "हल्के" थ्रेड्स हैं जिन्हें ऑपरेटिंग सिस्टम के बजाय JVM द्वारा प्रबंधित किया जाता है। इन्हें लाखों की संख्या में बनाया जा सकता है, और ये न्यूनतम मेमोरी की खपत करते हैं।
\n\nवर्चुअल थ्रेड बनाने का उदाहरण:
\n\npublic class VirtualThreadExample {\n public static void main(String[] args) throws InterruptedException {\n // 100,000 वर्चुअल थ्रेड बनाएं\n var threads = new Thread[100_000];\n for (int i = 0; i < threads.length; i++) {\n threads[i] = Thread.startVirtualThread(() -> {\n // ब्लॉकिंग I/O के साथ काम का अनुकरण\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n Thread.currentThread().interrupt();\n }\n });\n }\n for (Thread t : threads) {\n t.join();\n }\n System.out.println("सभी वर्चुअल थ्रेड पूर्ण हो गए!");\n }\n}\n\nअद्भुत, है ना?