कोटलिन में समवर्तीता और मल्टीथ्रेडिंग: A से Z तक
\n\nआधुनिक एप्लिकेशन अक्सर एक साथ कई कार्यों को निष्पादित करने की आवश्यकता रखते हैं। कोटलिन में, अन्य JVM भाषाओं की तरह, मल्टीथ्रेडिंग पारंपरिक रूप से Thread क्लास के माध्यम से कार्यान्वित की जाती है। हालाँकि, भाषा एक अधिक शक्तिशाली और सुरुचिपूर्ण उपकरण प्रदान करती है — कोरूटीन (coroutines)। इस लेख में, हम कोटलिन में समवर्तीता और मल्टीथ्रेडिंग के सभी पहलुओं को कवर करेंगे: बुनियादी अवधारणाओं से लेकर उन्नत तकनीकों तक।
1. मल्टीथ्रेडिंग की मूल बातें: Thread और Runnable
\n\nआइए क्लासिकल दृष्टिकोण से शुरू करें। कोटलिन में, जावा की तरह, आप सीधे एक थ्रेड बना सकते हैं:
\n\nfun main() {\n val thread = Thread {\n for (i in 1..5) {\n println("थ्रेड: $i")\n Thread.sleep(500)\n }\n }\n thread.start()\n println("मुख्य थ्रेड समाप्त")\n}\n\nहालाँकि, थ्रेड्स का मैन्युअल प्रबंधन कमियाँ रखता है:
\n- \n
- उच्च ओवरहेड — थ्रेड्स बनाना और नष्ट करना महंगा है। \n
- सिंक्रोनाइज़ेशन की जटिलता — रेस कंडीशन होना आसान है। \n
- थ्रेड्स की सीमित संख्या — सिस्टम केवल सीमित संख्या में थ्रेड्स बना सकता है। \n
साझा डेटा तक पहुँच को सिंक्रोनाइज़ करने के लिए, कीवर्ड synchronized या लॉक ReentrantLock का उपयोग किया जाता है:
class Counter {\n private var count = 0\n @Synchronized\n fun increment() {\n count++\n }\n}\n\n2. कोरूटीन — समवर्तीता के लिए आधुनिक दृष्टिकोण
\n\nकोरूटीन हल्के थ्रेड्स हैं जो क्लासिकल मल्टीथ्रेडिंग की समस्याओं को हल करते हैं। वे सिस्टम थ्रेड्स से बंधे नहीं होते हैं और एक ही थ्रेड पर कार्यों के बीच स्विच करके निष्पादित हो सकते हैं।
\n\n2.1. पहला कोरूटीन
\n\nकोरूटीन के साथ काम करने के लिए, आपको निर्भरता org.jetbrains.kotlinx:kotlinx-coroutines-core जोड़नी होगी। सबसे सरल कोरूटीन का उदाहरण:
import kotlinx.coroutines.*\n\nfun main() = runBlocking {\n launch {\n delay(1000L)\n println("दुनिया!")\n }\n println("नमस्ते,")\n}\n\nयहाँ runBlocking सामान्य कोड और कोरूटीन के बीच एक पुल है। launch एक नया कोरूटीन शुरू करता है, और delay Thread.sleep() का एनालॉग है, लेकिन यह थ्रेड को ब्लॉक नहीं करता है।
2.2. Suspend-फ़ंक्शन
\n\nकीवर्ड suspend थ्रेड को ब्लॉक किए बिना फ़ंक्शन के निष्पादन को रोकने की अनुमति देता है:
suspend fun fetchData(): String {\n delay(2000L) // नेटवर्क अनुरोध का अनुकरण\n return "डेटा प्राप्त हुआ"\n}\n\nfun main() = runBlocking {\n val result = async { fetchData() }\n println("प्रतीक्षा...")\n println(result.await())\n}\n\n2.3. संरचित समवर्तीता
\n\nकोटलिन संरचित समवर्तीता का समर्थन करता है — सभी चाइल्ड कोरूटीन पैरेंट कोरूटीन के समाप्त होने से पहले स्वचालित रूप से समाप्त हो जाते हैं:
\n\nfun main() = runBlocking {\n coroutineScope {\n launch {\n delay(1000L)\n println("कार्य 1")\n }\n launch {\n delay(500L)\n println("कार्य 2")\n }\n }\n println("सभी कार्य समाप्त")\n}\n\n3. उन्नत तकनीकें: Channel, Flow और Dispatchers
\n\n3.1. चैनल (Channel)
\n\nचैनल कोरूटीन के बीच डेटा साझा करने की अनुमति देते हैं। यह एक कतार का एनालॉग है:
\n\nfun main() = runBlocking {\n val channel = Channel<Int>()\n \n launch {\n for (i in 1..5) {\n channel.send(i * i)\n }\n channel.close()\n }\n \n for (value in channel) {\n println(value)\n }\n}\n\n3.2. Flow — कोल्ड डेटा स्ट्रीम
\n\nFlow एक रिएक्टिव स्ट्रीम है जो अनुरोध पर मान उत्सर्जित करता है:
fun simpleFlow(): Flow<Int> = flow {\n for (i in 1..3) {\n delay(