Kotlin में टास्क क्यू के साथ काम करना: शुरुआती लोगों के लिए
\nआधुनिक डेवलपमेंट में, अक्सर कई कार्यों को एसिंक्रोनस रूप से करने की आवश्यकता होती है: डाउनलोड प्रोसेस करना, API को अनुरोध भेजना, डेटाबेस के साथ काम करना। कोड के सही संगठन के बिना, यह अराजकता पैदा कर सकता है - कार्य अप्रत्याशित क्रम में निष्पादित होंगे, और सिस्टम संसाधन ओवरलोड हो जाएंगे। टास्क क्यू इस समस्या का समाधान करते हैं। इस लेख में, हम कोरूटीन और चैनल का उपयोग करके Kotlin में टास्क क्यू बनाने और उपयोग करने का तरीका समझेंगे। यह सामग्री शुरुआती डेवलपर्स के लिए है जो Kotlin की मूल बातों से परिचित हैं।
\n\nटास्क क्यू क्या है और इसकी आवश्यकता क्यों है?
\nटास्क क्यू एक डेटा संरचना है जो FIFO (फर्स्ट इन, फर्स्ट आउट) सिद्धांत पर काम करती है। आप क्यू के अंत में एक कार्य जोड़ते हैं, और एक विशेष हैंडलर (वर्कर) इसे शुरू से निकालता है और निष्पादित करता है। यह अनुमति देता है:
\n- \n
- निष्पादन को व्यवस्थित करना। कार्य एक-दूसरे से टकराते नहीं हैं। \n
- लोड को नियंत्रित करना। आप एक साथ निष्पादित किए जाने वाले कार्यों की संख्या को सीमित कर सकते हैं। \n
- एप्लिकेशन की प्रतिक्रियाशीलता बढ़ाना। भारी ऑपरेशन मुख्य थ्रेड को ब्लॉक नहीं करते हैं। \n
Kotlin में, एसिंक्रोनस क्यू के साथ काम करने के लिए मुख्य उपकरण कोरूटीन और उनका घटक Channel हैं। ये हल्के थ्रेड हैं जो बहुत अधिक संसाधनों का उपभोग नहीं करते हैं।
कोरूटीन के साथ काम करने के लिए प्रोजेक्ट सेटअप
\nकोड लिखने से पहले, सुनिश्चित करें कि आपके प्रोजेक्ट में आवश्यक डिपेंडेंसी शामिल हैं। यदि आप Gradle का उपयोग कर रहे हैं, तो फ़ाइल build.gradle.kts (या build.gradle) में जोड़ें:
dependencies {\n implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")\n implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Android के लिए\n}\nअब आप अपनी पहली क्यू बनाने के लिए तैयार हैं।
\n\nChannel का उपयोग करके एक सरल क्यू बनाना
\nChannel मूल रूप से एक तैयार क्यू है जो कोरूटीन के बीच डेटा स्थानांतरित कर सकता है। आइए एक बुनियादी उदाहरण देखें: हमारे पास एक प्रोड्यूसर है जो कार्य उत्पन्न करता है, और एक कंज्यूमर है जो उन्हें निष्पादित करता है।
import kotlinx.coroutines.*\nimport kotlinx.coroutines.channels.Channel\n\nfun main() = runBlocking {\n val channel = Channel<String>() // स्ट्रिंग के लिए एक चैनल बनाएँ\n\n // प्रोड्यूसर: कार्य भेजता है\n launch {\n val tasks = listOf("फ़ाइल डाउनलोड", "इमेज प्रोसेसिंग", "रिपोर्ट भेजना")\n for (task in tasks) {\n println("कार्य भेजा गया: $task")\n channel.send(task) // क्यू में जोड़ें\n delay(500) // कार्यों के बीच समय का अनुकरण\n }\n channel.close() // सभी कार्य भेजने के बाद चैनल बंद करें\n }\n\n // कंज्यूमर: कार्य निष्पादित करता है\n launch {\n for (task in channel) { // क्यू से कार्य पढ़ें\n println("निष्पादित हो रहा है: $task")\n delay(1000) // निष्पादन समय का अनुकरण\n println("पूर्ण हुआ: $task")\n }\n }\n\n println("मुख्य थ्रेड काम करता रहता है...")\n delay(5000) // पूरा होने की प्रतीक्षा करें\n}\nयहाँ क्या हो रहा है?
\n- \n
Channel<String>()एक नॉन-ब्लॉकिंग क्यू बनाता है। \n send()एक तत्व जोड़ता है,for (task in channel)उन्हें क्रम से पढ़ता है। \n - चैनल स्वचालित रूप से कंज्यूमर कोरूटीन को ब्लॉक करता है यदि क्यू खाली है, और प्रोड्यूसर को यदि क्यू भरा हुआ है (डिफ़ॉल्ट क्षमता 0 है, यानी रेंडेज़वस)। \n
प्रोग्राम का आउटपुट अनुक्रमिक होगा: कार्य जोड़ने के क्रम में एक के बाद एक सख्ती से निष्पादित होते हैं।
\n\nएकाधिक वर्कर्स और बफरिंग का प्रबंधन
\nवास्तविक एप्लिकेशन में अक्सर समानांतर प्रोसेसिंग की आवश्यकता होती है। मान लीजिए, हमारे पास 10 कार्य हैं, और हम उन्हें प्रोसेस करना चाहते हैं