Kotlin में समवर्तीता और मल्टीथ्रेडिंग: उन्नत स्तर
\nKotlin में आधुनिक डेवलपमेंट में, विशेष रूप से सर्वर और Android ऐप्स के लिए, समवर्तीता का कुशल प्रबंधन प्रदर्शन और प्रतिक्रियाशीलता की कुंजी है। उन्नत स्तर पर, केवल कोरूटीन शुरू करना पर्याप्त नहीं है। डेटा तक पहुंच को प्रभावी ढंग से सिंक्रोनाइज़ करना, थ्रेड्स को प्रबंधित करना और "भयानक" लॉक से बचना समझना आवश्यक है। इस लेख में, हम उन्नत तकनीकों पर चर्चा करेंगे: kotlinx.coroutines की बारीकियों से लेकर थ्रेड-सेफ कलेक्शन और चैनल तक।
1. कोरूटीन में गहराई से उतरना: Structured Concurrency और Scopes
\nउन्नत कार्य का आधार Structured Concurrency है। यह एक सिद्धांत है जिसमें कोरूटीन का जीवनचक्र एक स्कोप से बंधा होता है। यदि पैरेंट कोरूटीन रद्द हो जाती है, तो उसके सभी चाइल्ड कार्य स्वचालित रूप से समाप्त हो जाते हैं। यह मेमोरी लीक और अनियंत्रित प्रक्रियाओं को रोकता है।
\nउन्नत स्तर पर, आपको ग्लोबल GlobalScope पर निर्भर रहने के बजाय अपने स्वयं के स्कोप बनाने चाहिए।
import kotlinx.coroutines.*\nimport kotlin.coroutines.CoroutineContext\n\nclass DataRepository {\n // डिस्पैचर और एक्सेप्शन हैंडलर के साथ अपना स्वयं का स्कोप\n private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler { _, throwable ->\n println("अनहैंडल एरर: ${throwable.message}")\n })\n\n fun loadData() {\n scope.launch {\n // चाइल्ड कोरूटीन\n val data = async { fetchFromNetwork() }\n val cache = async { loadFromCache() }\n process(data.await(), cache.await())\n }\n }\n\n fun cleanup() {\n scope.cancel() // स्कोप में सभी कोरूटीन रद्द करें\n }\n}\n\nSupervisorJob का उपयोग करें जब एक चाइल्ड कोरूटीन की विफलता से बाकी को रद्द नहीं होना चाहिए। यह UI लेयर या समानांतर स्वतंत्र अनुरोधों के लिए महत्वपूर्ण है।
2. थ्रेड-सेफ कलेक्शन और एटॉमिक ऑपरेशन
\nकोरूटीन के साथ भी, यदि आप साझा परिवर्तनीय डेटा के साथ काम कर रहे हैं, तो सिंक्रोनाइज़ेशन आवश्यक है। Kotlin कई दृष्टिकोण प्रदान करता है:
\n- \n
- एटॉमिक प्रकार (
AtomicInteger,AtomicReference) — सरल काउंटर और फ्लैग के लिए। \n - थ्रेड-सेफ कलेक्शन (
ConcurrentHashMap,CopyOnWriteArrayList) — जटिल संरचनाओं के लिए। \n - Mutex
kotlinx.coroutinesसे — कोरूटीन के अंदर क्रिटिकल सेक्शन के लिए। \n
import kotlinx.coroutines.*\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport java.util.concurrent.ConcurrentHashMap\nimport java.util.concurrent.atomic.AtomicInteger\n\nclass SafeCounter {\n private val mutex = Mutex()\n private var counter = 0\n\n suspend fun increment() {\n mutex.withLock {\n counter++ // क्रिटिकल सेक्शन\n }\n }\n\n fun getCounter(): Int = counter\n}\n\nclass CacheManager {\n private val cache = ConcurrentHashMap<String, String>()\n private val hitCount = AtomicInteger(0)\n\n fun put(key: String, value: String) {\n cache[key] = value\n }\n\n fun get(key: String): String? {\n val result = cache[key]\n if (result != null) hitCount.incrementAndGet()\n return result\n }\n}\n\nमहत्वपूर्ण: Mutex एक suspend-फ़ंक्शन है, इसलिए यह थ्रेड को ब्लॉक नहीं करता, बल्कि कोरूटीन को रोकता है। यह synchronized से अधिक कुशल है।
3. चैनल (Channels) और Flow: रिएक्टिव डेटा स्ट्रीम
\nकोरूटीन के बीच डेटा ट्रांसफर करने के लिए Channels (कोरूटीन के लिए BlockingQueue का एनालॉग) और Flow (कोल्ड एसिंक्रोनस स्ट्रीम) का उपयोग करें।
चैनल: Producer-Consumer
\nimport kotlinx.coroutines.channels.*\nimport kotlinx.coroutines.*\n\nfun Corout