Coroutines (कोरूटीन) Kotlin में एसिंक्रोनस प्रोग्रामिंग के लिए हल्के थ्रेड हैं, जो kotlinx.coroutines लाइब्रेरी के माध्यम से उपलब्ध हैं। JetBrains Kotlin Documentation, 2026 के अनुसार, Coroutines थ्रेड को ब्लॉक किए बिना फ़ंक्शन निष्पादन को स्थगित करने की अनुमति देते हैं, पारंपरिक Thread के विपरीत। कोरूटीन सीमित थ्रेड पूल पर चलते हैं, जो उन्हें नेटिव थ्रेड की तुलना में हज़ार गुना हल्का बनाता है। Kotlin Coroutines Android Jetpack, Retrofit, Room और Android इकोसिस्टम की अन्य लोकप्रिय लाइब्रेरीज़ के साथ पूरी तरह से एकीकृत हैं।
मुख्य बिंदु
Coroutines Kotlin में एक एसिंक्रोनस प्रोग्रामिंग तंत्र है, जो kotlinx.coroutines लाइब्रेरी में कार्यान्वित है। ऑपरेटिंग सिस्टम थ्रेड के विपरीत, कोरूटीन किसी विशिष्ट थ्रेड से बंधे नहीं होते: वे एक थ्रेड पर रुक सकते हैं और दूसरे पर फिर से शुरू हो सकते हैं। एक ही थ्रेड हजारों कोरूटीन को न्यूनतम ओवरहेड के साथ निष्पादित कर सकता है।
कोरूटीन Kotlin 1.3 (2018) में एक प्रयोगात्मक सुविधा के रूप में दिखाई दिए और Kotlin 1.5 (2021) में स्थिर हो गए। Coroutines async/await के समान callback hell समस्या को हल करते हैं, लेकिन अधिक समृद्ध API प्रदान करते हैं: चैनल (Channel), Flow, Job पदानुक्रम में अपवाद हैंडलिंग और Android Lifecycle के साथ सीधा एकीकरण।
JetBrains (2025) के अनुसार, प्रत्येक कोरूटीन लगभग 100 बाइट्स मेमोरी की खपत करता है जबकि नेटिव थ्रेड के लिए 1+ MB। यह एक ही एप्लिकेशन में OutOfMemoryError के जोखिम के बिना लाखों कोरूटीन चलाने की अनुमति देता है। यह कोरूटीन की हल्कापन ही है जो उन्हें Android में एसिंक्रोनसिटी के लिए पसंदीदा उपकरण बनाता है।
प्रत्येक Kotlin कोरूटीन Continuation Passing Style (CPS) के माध्यम से एक state machine में संकलित होता है। कंपाइलर प्रत्येक suspend फ़ंक्शन में एक छिपा हुआ Continuation पैरामीटर जोड़ता है। Continuation में पुनः आरंभ बिंदु और सभी स्थानीय चर होते हैं। जब कोरूटीन रुकता है, runtime Continuation को सहेजता है, और जब यह फिर से शुरू होता है, तो इसे Dispatcher पूल के किसी भी उपलब्ध थ्रेड पर पुनर्स्थापित करता है।
suspend एक Kotlin कीवर्ड है जो किसी फ़ंक्शन को स्थगित करने योग्य के रूप में चिह्नित करता है। ऐसे फ़ंक्शन को केवल दूसरे suspend फ़ंक्शन या कोरूटीन से ही कॉल किया जा सकता है। suspend फ़ंक्शन के अंदर, आप किसी भी क्रम में अन्य suspend फ़ंक्शन को कॉल कर सकते हैं, और प्रत्येक कॉल बिंदु एक संभावित स्थगन बिंदु है।
तंत्र सरल है: जब कोई suspend फ़ंक्शन दूसरे suspend फ़ंक्शन को कॉल करता है, तो वह उस बिंदु पर रुक जाता है, थ्रेड को मुक्त करता है। कॉल किए गए फ़ंक्शन के पूरा होने के बाद, runtime सहेजी गई जगह से निष्पादन जारी रखता है। इसे cooperative cancellation कहा जाता है — कोई थ्रेड ब्लॉक नहीं होता।
महत्वपूर्ण: suspend फ़ंक्शन डिफ़ॉल्ट रूप से एसिंक्रोनस नहीं है। यदि launch या async का उपयोग नहीं किया जाता है तो निष्पादन क्रम अनुक्रमिक रहता है। suspend केवल फ़ंक्शन को थ्रेड को ब्लॉक किए बिना रुकने और कोरूटीन संदर्भ का हिस्सा बनने की अनुमति देता है। Continuation Passing Style एक संकलन मॉडल है जहाँ प्रत्येक suspend फ़ंक्शन को एक छिपा हुआ Continuation कॉलबैक प्राप्त होता है, और कंपाइलर स्थगन और पुनः आरंभ को प्रबंधित करने के लिए एक state machine उत्पन्न करता है।
CoroutineScope एक संदर्भ है जो कोरूटीन के जीवनचक्र को परिभाषित करता है। सभी कोरूटीन को एक scope के अंदर लॉन्च किया जाना चाहिए। जब scope रद्द किया जाता है (जैसे, Activity समाप्त होने पर), इसके सभी चाइल्ड कोरूटीन स्वचालित रूप से रद्द हो जाते हैं। यह बैकग्राउंड टास्क लीक को रोकता है। Android Jetpack प्रत्येक घटक के लिए तैयार scopes प्रदान करता है: ViewModel के लिए viewModelScope और Activity/Fragment के लिए lifecycleScope, जो संबंधित घटक के नष्ट होने पर स्वचालित रूप से रद्द हो जाते हैं।
संरचित समवर्तीता (Structured Concurrency) एक सिद्धांत है जो गारंटी देता है कि कोरूटीन तब तक पूरा नहीं होगा जब तक उसके सभी चाइल्ड कोरूटीन पूरे नहीं हो जाते। Job पदानुक्रम एक पेड़ बनाता है: एक रूट कोरूटीन एक parent job बनाता है, चाइल्ड child jobs बनाते हैं। parent job को रद्द करना सभी चाइल्ड में फैल जाता है। Structured Concurrency कोरूटीन और थ्रेड के बीच एक मूलभूत अंतर है।
| Scope | कहाँ उपयोग होता है | रद्दीकरण |
|---|---|---|
| GlobalScope | केवल daemon कार्यों के लिए | स्वचालित रूप से रद्द नहीं होता |
| viewModelScope | Android ViewModel | ViewModel साफ़ होने पर |
| lifecycleScope | Android Activity/Fragment | lifecycle नष्ट होने पर |
| coroutineScope | suspend फ़ंक्शन के अंदर | पैरेंट job रद्द होने पर |
सामान्य Job एक चाइल्ड कोरूटीन के विफल होने पर सभी सिबलिंग को रद्द कर देता है। SupervisorJob एक अपवाद है: एक चाइल्ड कोरूटीन में विफलता दूसरों को प्रभावित नहीं करती। यह महत्वपूर्ण है जब कई स्वतंत्र कार्य समानांतर में निष्पादित होते हैं, और उनमें से एक दूसरों को रद्द किए बिना क्रैश हो सकता है।
Dispatchers यह निर्धारित करते हैं कि कोरूटीन किन थ्रेड पर निष्पादित होते हैं। Dispatchers.Main — मुख्य Android UI थ्रेड। Dispatchers.IO — ब्लॉकिंग ऑपरेशन (नेटवर्क, डिस्क) के लिए पूल। Dispatchers.Default — CPU-गहन कार्यों के लिए। Dispatchers.Unconfined — वर्तमान थ्रेड में शुरू होता है लेकिन उस पर बने रहने की गारंटी नहीं देता। सही Dispatcher चुनना प्रदर्शन के लिए महत्वपूर्ण है: Default पर IO कार्य कम्प्यूट पूल को ब्लॉक करेगा, जबकि IO पर CPU कार्य अनावश्यक थ्रेड बनाएगा।
withContext — कोरूटीन के अंदर Dispatcher बदलने के लिए एक फ़ंक्शन। उदाहरण के लिए, JSON पार्स करने वाला suspend फ़ंक्शन गणना के लिए Dispatchers.Default पर स्विच कर सकता है और UI अपडेट के लिए Dispatchers.Main पर वापस आ सकता है। withContext Android डेवलपमेंट में सबसे अधिक उपयोग किया जाने वाला बिल्डर है।
launch — कोरूटीन लॉन्च करता है, Job लौटाता है, परिणाम नहीं लौटाता (fire-and-forget)। async — कोरूटीन लॉन्च करता है, Deferred लौटाता है जिससे await के माध्यम से परिणाम प्राप्त किया जा सकता है। runBlocking — कोरूटीन निष्पादित करने के लिए वर्तमान थ्रेड को ब्लॉक करता है (केवल परीक्षण और main फ़ंक्शन के लिए)। बिल्डर चुनना परिदृश्य पर निर्भर करता है: launch घटनाओं और अपडेट के लिए उपयुक्त है, async परिणाम वाले कार्यों के लिए, runBlocking केवल परीक्षण या प्रवेश बिंदुओं के लिए।
आइए तीन व्यावहारिक परिदृश्यों पर विचार करें: launch के साथ एक बुनियादी कोरूटीन, async के साथ समानांतर कॉल, और SupervisorJob के साथ त्रुटि हैंडलिंग।
viewModelScope.launch ViewModel संदर्भ में कोरूटीन लॉन्च करता है। जब ViewModel साफ़ होता है, कोरूटीन स्वचालित रूप से रद्द हो जाता है।
class ProfileViewModel : ViewModel() {
fun loadUser() {
viewModelScope.launch(Dispatchers.IO) {
val user = api.fetchUser()
withContext(Dispatchers.Main) {
showUser(user)
}
}
}
}
coroutineScope async के साथ तीन अनुरोधों को समानांतर में लॉन्च करता है। परिणाम .await() के माध्यम से एकत्र किए जाते हैं। यदि कोई अनुरोध विफल होता है, तो सभी रद्द हो जाते हैं।
suspend fun loadDashboard(): Dashboard = coroutineScope {
val user = async { api.fetchUser() }
val posts = async { api.fetchPosts() }
val stats = async { api.fetchStats() }
Dashboard(user.await(), posts.await(), stats.await())
}
SupervisorJob प्रत्येक कोरूटीन को स्वतंत्र रूप से पूरा होने देता है। एक अनुरोध में त्रुटि दूसरों को रद्द नहीं करती।
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
try { api.fetchUsers() } catch (e: Exception) { log(e) }
}
scope.launch {
try { api.fetchPosts() } catch (e: Exception) { log(e) }
}
थ्रेड (Thread) एक ऑपरेटिंग सिस्टम प्रिमिटिव है। प्रत्येक थ्रेड का अपना स्टैक (~1 MB) होता है और इसे बनाने और स्विच करने के लिए सिस्टम कॉल की आवश्यकता होती है। कोरूटीन एक भाषा प्रिमिटिव है, जो OS से बंधा नहीं है। वे स्थिति सहेजने के लिए Continuation का उपयोग करते हैं और सिस्टम कॉल के बिना रनटाइम स्तर पर स्विच करते हैं।
Google (2025) के अनुसार, थ्रेड के बजाय कोरूटीन का उपयोग करने से Android एप्लिकेशन में बैकग्राउंड कार्यों के लिए मेमोरी खपत 90–95% तक कम हो जाती है। सभी आधुनिक Android लाइब्रेरीज़ (Retrofit, Room, WorkManager) में suspend फ़ंक्शन के माध्यम से अंतर्निहित कोरूटीन समर्थन है। Ktor (JetBrains का HTTP क्लाइंट फ्रेमवर्क) भी पूरी तरह से कोरूटीन पर बना है, जो बिना कॉलबैक API के प्रत्येक अनुरोध के लिए suspend फ़ंक्शन प्रदान करता है। Room DAO में suspend फ़ंक्शन के माध्यम से कोरूटीन का समर्थन करता है, जो मुख्य थ्रेड को ब्लॉक किए बिना डेटाबेस क्वेरी निष्पादित करने की अनुमति देता है।
थ्रेड नेटिव कोड के लिए JNI के माध्यम से, लंबे समय तक चलने वाली CPU-गहन ब्लॉकिंग कॉल (वीडियो रेंडरिंग, सिमुलेशन) और C लाइब्रेरीज़ के साथ एकीकरण के लिए आवश्यक बने हुए हैं। बाकी सबके लिए — कोरूटीन।
अक्सर पूछे जाने वाले प्रश्न
कोरूटीन कार्य की एक स्थगित करने योग्य इकाई है जो मौजूदा थ्रेड पर निष्पादित होती है। थ्रेड अपने स्वयं के स्टैक के साथ एक सिस्टम संसाधन है। कोरूटीन थ्रेड की तुलना में हज़ारों गुना हल्के होते हैं और स्थगित होने पर संसाधनों को ब्लॉक नहीं करते।
Dispatchers.IO ब्लॉकिंग I/O संचालन (नेटवर्क, फ़ाइलें) के लिए डिज़ाइन किया गया है और ज़रूरत पड़ने पर नए थ्रेड बना सकता है। Dispatchers.Default में CPU-गहन गणनाओं के लिए एक निश्चित आकार का पूल (CPU कोर की संख्या) होता है।
Job.cancel() कोरूटीन और उसके सभी चाइल्ड को रद्द करता है। कोरूटीन के अंदर रद्दीकरण की जाँच करने के लिए, ensureActive() का उपयोग करें — यदि कोरूटीन रद्द किया गया है तो यह CancellationException फेंकता है।
हाँ — kotlinx-coroutines-rx3 लाइब्रेरी के माध्यम से। यह Observable/Single को suspend फ़ंक्शन में बदलने और flowable के माध्यम से वापस करने के लिए awaitSingle, awaitFirst और अन्य फ़ंक्शन प्रदान करती है।
Flow एक कोल्ड एसिंक्रोनस डेटा स्ट्रीम है, जो कोरूटीन में RxJava Observable के समकक्ष है। Flow क्रमिक रूप से मान उत्सर्जित करता है और अपवाद या सफलता के साथ पूरा होता है। यह map, filter, catch और अन्य ऑपरेटरों का समर्थन करता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें