मोबाइल एप्लिकेशन में Starvation — सार, कारण और थ्रेड स्टार्वेशन को रोकने के तरीके

लेखक: IT Sectr प्रकाशित: 2026-03-18 पढ़ने का समय: 10 मिनट

Starvation (थ्रेड स्टार्वेशन) — एक ऐसी स्थिति है जिसमें थ्रेड कार्य जारी रखने के लिए आवश्यक संसाधन तक पहुंच प्राप्त नहीं कर पाता, भले ही वह निष्पादन के लिए तैयार हो। Baeldung (Java Thread Starvation, 2024) के अनुसार, स्टार्वेशन अनुचित शेड्यूलिंग के कारण उत्पन्न होता है, जब निम्न-प्राथमिकता वाले थ्रेड को उच्च-प्राथमिकता वाले थ्रेड के पक्ष में लगातार स्थगित किया जाता है। Deadlock के विपरीत, Starvation थ्रेड को ब्लॉक नहीं करता — वह RUNNABLE अवस्था में रहता है लेकिन कभी CPU समय प्राप्त नहीं करता।

मुख्य बातें

  • Starvation — एक ऐसी स्थिति जहाँ थ्रेड निष्पादन के लिए तैयार होने के बावजूद संसाधन तक पहुंच प्राप्त नहीं कर पाता
  • Deadlock के विपरीत, स्टार्वेशन में थ्रेड RUNNABLE अवस्था में रहता है — वह ब्लॉक नहीं है, लेकिन प्रगति नहीं करता
  • अनुचित शेड्यूलिंग (उदाहरण के लिए, synchronized के माध्यम से सिंक्रोनाइज़ेशन) — JVM पर Starvation का मुख्य कारण
  • Fair Lock (ReentrantLock(true)) लॉक अधिग्रहण के लिए निष्पक्ष FIFO क्रम सुनिश्चित करता है
  • Thread Priority को मोबाइल डेवलपमेंट में बदलने की अनुशंसा नहीं की जाती — Android Runtime स्वयं प्राथमिकताओं का प्रबंधन करता है

Starvation क्या है?

Starvation (थ्रेड स्टार्वेशन) — एक मल्टीथ्रेडिंग समस्या है जहाँ एक थ्रेड अपने कार्य को पूरा करने के लिए आवश्यक संसाधन तक पहुंच प्राप्त नहीं कर पाता, भले ही संसाधन किसी अन्य थ्रेड द्वारा स्थायी रूप से लॉक न किया गया हो। थ्रेड RUNNABLE अवस्था में है, लेकिन शेड्यूलर या सिंक्रोनाइज़ेशन तंत्र व्यवस्थित रूप से अन्य थ्रेड के पक्ष में इसके निष्पादन को स्थगित करता है।

मोबाइल डेवलपमेंट में, Starvation असमान कार्य निष्पादन के रूप में प्रकट होता है: कुछ ऑपरेशन तुरंत निष्पादित होते हैं, जबकि अन्य भयावह देरी से ग्रस्त होते हैं। उदाहरण के लिए, एक पृष्ठभूमि डेटा सिंक्रोनाइज़ेशन थ्रेड कभी भी डेटाबेस तक पहुंच प्राप्त नहीं कर सकता यदि UI थ्रेड और एनिमेशन हैंडलर लगातार इसे आगे निकल जाते हैं। Android Developer Blog (Performance Matters, 2023) के अनुसार, Android पर लगभग 12% मिस्ड फ्रेम (jank) रेंडरिंग पर निर्भर पृष्ठभूमि कार्यों के Starvation के कारण होते हैं।

Starvation और Deadlock के बीच मुख्य अंतर प्रतिवर्तीता है। यदि सिस्टम लोड कम हो जाता है या प्राथमिकताएं पुनर्वितरित हो जाती हैं, तो भूखा थ्रेड संसाधन प्राप्त कर सकता है और अपना कार्य पूरा कर सकता है। हालांकि, निरंतर उच्च लोड के तहत, Starvation अनिश्चित काल तक रह सकता है, जिससे एप्लिकेशन के फ्रोजन होने का आभास होता है।

थ्रेड स्टार्वेशन के कारण

अनुचित लॉक (Non-Fair Locks)

Java और Kotlin में synchronized अनुचित तंत्र का एक उत्कृष्ट उदाहरण है। उच्च प्रतिस्पर्धा के तहत, JVM लगातार उन्हीं सक्रिय थ्रेड को लॉक प्रदान कर सकता है, जबकि अन्य थ्रेड लगातार दौड़ हार जाते हैं। यह JVM की बग नहीं बल्कि डिज़ाइन ट्रेड-ऑफ है: अनुचित लॉक पहुंच की निष्पक्षता की कीमत पर उच्च थ्रूपुट प्रदान करते हैं। 4–8 थ्रेड वाले मोबाइल एप्लिकेशन के लिए, यह समस्या विशेष रूप से प्रासंगिक है।

प्राथमिकताओं का गलत उपयोग

अलग-अलग थ्रेड प्राथमिकताएं सेट करने से निम्न-प्राथमिकता वाले थ्रेड का Starvation हो सकता है। Android Runtime में, Linux CFS (Completely Fair Scheduler) शेड्यूलर CPU समय को प्राथमिकताओं के अनुपात में वितरित करता है, और यदि उच्च-प्राथमिकता वाले थ्रेड लगातार सक्रिय हैं, तो निम्न-प्राथमिकता वाले थ्रेड को कभी CPU समय नहीं मिल सकता है। Google Android में थ्रेड प्राथमिकताएं बदलने से सख्ती से मना करता है — सिस्टम स्वयं उनका प्रबंधन करता है।

लंबे क्रिटिकल सेक्शन

यदि कोई थ्रेड बहुत लंबे समय तक लॉक रखता है (synchronized ब्लॉक के अंदर भारी गणना, नेटवर्क अनुरोध या फ़ाइल संचालन करता है), तो उस लॉक की प्रतीक्षा करने वाले अन्य थ्रेड भूखे रह जाते हैं। यह Android में विशेष रूप से खतरनाक है, जहां UI थ्रेड पर लंबे संचालन ANR का कारण बनते हैं, और क्रिटिकल सेक्शन को ऑप्टिमाइज़ किए बिना उन्हें पृष्ठभूमि थ्रेड में ले जाना केवल Starvation समस्या को वर्कर थ्रेड में स्थानांतरित करता है।

Kotlin कोड में Starvation का उदाहरण

एक उदाहरण पर विचार करें जहाँ अनुचित शेड्यूलिंग के कारण एक थ्रेड बहुत बार लॉक प्राप्त करता है। Starvation को एक उच्च-प्राथमिकता वाले थ्रेड के अनंत लूप के माध्यम से प्रदर्शित किया जाता है जो निम्न-प्राथमिकता वाले थ्रेड को साझा संसाधन तक पहुंचने से रोकता है।

kotlin
class SharedResource {
    private val lock = Any()

    fun criticalSection(id: String) {
        synchronized(lock) {
            println("$id को पहुंच मिली")
            Thread.sleep(10)  // कार्य का अनुकरण
        }
    }
}

fun main() {
    val resource = SharedResource()

    // उच्च-प्राथमिकता वाला थ्रेड — लगातार सक्रिय
    val highPriority = Thread {
        while (true) {
            resource.criticalSection("High")
        }
    }

    // निम्न-प्राथमिकता वाला थ्रेड — कभी पहुंच नहीं मिल सकती
    val lowPriority = Thread {
        while (true) {
            resource.criticalSection("Low")
        }
    }

    highPriority.start()
    lowPriority.start()
    // "Low" कभी संदेश प्रिंट नहीं कर सकता — Starvation!
}

इस उदाहरण में, highPriority थ्रेड लगातार लॉक प्राप्त करता है और इसे केवल 10 ms के लिए छोड़ता है। synchronized की अनुचित प्रकृति के कारण, JVM शेड्यूलर सबसे अधिक संभावना उसी थ्रेड को फिर से लॉक प्रदान करेगा जिसने अभी-अभी इसे छोड़ा है — निम्न-प्राथमिकता वाला थ्रेड भूखा रह जाता है। समाधान ReentrantLock(true) का उपयोग fair फ्लैग के साथ करना है, जो FIFO प्रतीक्षा क्रम सुनिश्चित करता है।

फेयर लॉक के साथ सही किया गया संस्करण संसाधन तक निष्पक्ष पहुंच सुनिश्चित करता है।

kotlin
class FairSharedResource {
    private val fairLock = ReentrantLock(true)  // fair = true

    fun criticalSection(id: String) {
        fairLock.lock()
        try {
            println("$id को पहुंच मिली (fair)")
            Thread.sleep(10)
        } finally {
            fairLock.unlock()
        }
    }
}

Starvation vs Deadlock vs Livelock

तीन क्लासिक मल्टीथ्रेडिंग समस्याएं — Starvation, Deadlock और Livelock — अक्सर एक साथ समूहित की जाती हैं, लेकिन उनके तंत्र और समाधान भिन्न होते हैं। Starvation — थ्रेड तैयार है लेकिन संसाधन प्राप्त नहीं कर सकता। Deadlock — थ्रेड चक्रीय प्रतीक्षा द्वारा अवरुद्ध हैं। Livelock — थ्रेड सक्रिय हैं लेकिन कोई प्रगति नहीं करते।

पैरामीटरStarvationDeadlockLivelock
थ्रेड अवस्थाRUNNABLEBLOCKEDRUNNABLE
प्रगतिकोई नहींकोई नहींकोई नहीं (हालांकि सक्रिय)
CPU उपयोगकमन्यूनतमउच्च (100% तक)
कारणअनुचित शेड्यूलिंगचक्रीय प्रतीक्षासंघर्ष पर समान प्रतिक्रिया
मुख्य सुधारFair Lock, क्रिटिकल सेक्शन छोटा करनालॉक पदानुक्रमपुनः प्रयास सीमा, exponential backoff

Starvation को Deadlock से कम गंभीर माना जाता है क्योंकि यह घातक नहीं है — कम लोड के तहत, भूखा थ्रेड अंततः निष्पादित होगा। हालांकि, वास्तविक Android उपयोग में, जहाँ मेमोरी और CPU सीमित हैं, Starvation मिनटों तक रह सकता है, जो एक अस्वीकार्य UX बनाता है।

Starvation का पता कैसे लगाएं

Thread Dump को छोटे अंतराल पर बार-बार लेना — स्टार्वेशन का पता लगाने की मूल विधि है। यदि कोई थ्रेड लगातार RUNNABLE अवस्था में है लेकिन उसका कॉल स्टैक कई डंप में नहीं बदलता — यह Starvation का एक क्लासिक संकेत है। Android Studio में, समय के साथ थ्रेड स्थिति रिकॉर्डिंग के लिए Android Profiler का उपयोग करें।

कार्यों के निष्पादन समय की निगरानी के माध्यम से स्वचालित पहचान संभव है। यदि एक अनुमानित निष्पादन समय (जैसे, 50 ms) वाला कार्य 5 सेकंड या उससे अधिक लेता है — Starvation की उच्च संभावना है। मोबाइल एप्लिकेशन में, Firebase Performance Monitoring आपको क्रिटिकल सेक्शन के लिए कस्टम ट्रेस सेट करने और सीमा पार होने पर सूचनाएं प्राप्त करने की अनुमति देता है।

synchronized ब्लॉक के कारण होने वाले Starvation के निदान के लिए, Java Flight Recorder (JFR) (OpenJDK API के माध्यम से Android पर उपलब्ध) या Async Profiler का उपयोग करें। ये उपकरण दिखाते हैं कि किन मॉनिटरों में सबसे अधिक प्रतीक्षा समय है और कौन से थ्रेड प्रत्येक मॉनिटर के लिए प्रतिस्पर्धा कर रहे हैं। JFR डेटा अपने अंतर्निहित प्रोफाइलर के माध्यम से IntelliJ IDEA Ultimate के साथ एकीकृत होता है।

थ्रेड स्टार्वेशन को रोकने के तरीके

Fair Lock (true फ्लैग के साथ ReentrantLock)

ReentrantLock(true) सुनिश्चित करता है कि थ्रेड FIFO क्रम में लॉक प्राप्त करें। synchronized के विपरीत, एक फेयर लॉक उस थ्रेड को तुरंत लॉक पुनः प्राप्त करने की अनुमति नहीं देता जिसने अभी-अभी इसे छोड़ा है। यह Starvation को पूरी तरह से समाप्त करता है, हालांकि कतार बनाए रखने के ओवरहेड के कारण कुल थ्रूपुट 10–20% कम हो जाता है।

लॉक-फ्री परमाणु संरचनाएं

लॉक-फ्री डेटा संरचनाएं (ConcurrentHashMap, AtomicReference, LongAdder) परिभाषा के अनुसार Starvation को समाप्त करती हैं, क्योंकि उनमें ऐसे लॉक नहीं होते जो एक थ्रेड द्वारा रखे जा सकें। सभी ऑपरेशन CPU CAS निर्देशों का उपयोग करते हैं जो सीमित चरणों में कम से कम एक थ्रेड की प्रगति सुनिश्चित करते हैं। मोबाइल डेवलपमेंट के लिए, कार्य कतारों के लिए ConcurrentLinkedQueue को प्राथमिकता दें।

छोटे क्रिटिकल सेक्शन

लॉक धारण समय को कम करना Starvation के जोखिम को कम करने का एक सार्वभौमिक तरीका है। भारी संचालन (नेटवर्क, डिस्क I/O, जटिल गणना) को synchronized ब्लॉक के बाहर ले जाएं। उन परिदृश्यों के लिए ReadWriteLock का उपयोग करें जहाँ पाठकों को दुर्लभ लेखकों के कारण भूखा नहीं रहना चाहिए। Kotlin Coroutines लाइब्रेरी एक suspending तंत्र के साथ Mutex प्रदान करती है जो OS थ्रेड को ब्लॉक नहीं करता।

कंडीशन वेरिएबल और सिग्नल

Condition.await() और signal() का उपयोग सावधानी से किया जाना चाहिए: Condition पर प्रतीक्षा करने वाला थ्रेड अन्य थ्रेड के साथ जागता है (spurious wakeup), और सभी लॉक के लिए प्रतिस्पर्धा करते हैं। यदि एक थ्रेड await के तुरंत बाद प्रतीक्षा में लौट आता है जबकि अन्य लॉक प्राप्त करने में सफल हो जाते हैं, तो भूखा थ्रेड अनिश्चित काल तक जाग और सो सकता है। पुनः जांच सुनिश्चित करने के लिए हमेशा if के बजाय while लूप में स्थिति की जांच करें।

अक्सर पूछे जाने वाले प्रश्न

Starvation और Priority Inversion में क्या अंतर है?

Priority Inversion — एक ऐसी स्थिति है जहाँ निम्न-प्राथमिकता वाला थ्रेड एक लॉक रखता है जिसकी उच्च-प्राथमिकता वाले थ्रेड को आवश्यकता होती है। परिणामस्वरूप, उच्च-प्राथमिकता वाला थ्रेड निम्न-प्राथमिकता वाले की प्रतीक्षा करता है — प्राथमिकताएं उलट जाती हैं। Starvation एक व्यापक समस्या है: थ्रेड प्राथमिकता की परवाह किए बिना, अनुचित शेड्यूलिंग या लंबे क्रिटिकल सेक्शन के कारण संसाधन प्राप्त नहीं कर पाता।

क्या एकल-थ्रेड एप्लिकेशन में Starvation हो सकता है?

नहीं, Starvation एक मल्टीथ्रेडिंग समस्या है। एकल-थ्रेड कोड में संसाधन प्रतिस्पर्धा या थ्रेड शेड्यूलिंग नहीं होती। हालांकि, Starvation अतुल्यकालिक एकल-थ्रेड कोड (उदाहरण के लिए, JavaScript इवेंट लूप) में हो सकता है यदि एक माइक्रोटास्क शून्य विलंब के साथ setTimeout के माध्यम से दूसरों के निष्पादन को अनिश्चित काल तक स्थगित करता है।

Java Memory Model Starvation से कैसे संबंधित है?

JMM (Java Memory Model) थ्रेड के बीच परिवर्तनों की दृश्यता के नियमों को परिभाषित करता है लेकिन निष्पक्ष शेड्यूलिंग की गारंटी नहीं देता। synchronized, JMM के अनुसार, अनुक्रमिक स्थिरता — बुनियादी शुद्धता — सुनिश्चित करता है, लेकिन Starvation को नहीं रोकता। निष्पक्षता के लिए JMM में निर्दिष्ट नहीं किए गए अतिरिक्त तंत्रों की आवश्यकता होती है।

Android UI थ्रेड में Starvation क्या है?

UI थ्रेड (Main Thread) शास्त्रीय अर्थों में भूखा नहीं रह सकता क्योंकि इसकी सर्वोच्च प्राथमिकता है। हालांकि, Starvation तब होता है जब UI थ्रेड भूखे पृष्ठभूमि थ्रेड से परिणाम की प्रतीक्षा करता है। एक विशिष्ट परिदृश्य: AsyncTask या कोरूटीन डेटा लोड करता है लेकिन अन्य थ्रेड के साथ प्रतिस्पर्धा के कारण डेटाबेस तक पहुंच प्राप्त नहीं कर पाता, और UI प्रतीक्षा में फ्रीज हो जाता है।

Kotlin Coroutines में Starvation को कैसे रोकें?

कोरूटीन में, Starvation को रोकने के लिए, थ्रेड समाप्ति से बचने के लिए Dispatchers.IO पर limitedParallelism का उपयोग करें। सिंक्रोनाइज़ेशन के लिए, kotlinx.coroutines.sync से Mutex का उपयोग करें — यह थ्रेड को ब्लॉक करने के बजाय कोरूटीन को निलंबित करता है, जिससे स्टार्वेशन का जोखिम कम होता है। कोरूटीन में runBlocking से बचें, क्योंकि यह पूल थ्रेड पर कब्जा कर सकता है और अन्य कोरूटीन के Starvation का कारण बन सकता है।

सारांश

  • Starvation — एक ऐसी स्थिति जहाँ थ्रेड निष्पादन के लिए तैयार है लेकिन अनुचित शेड्यूलिंग के कारण संसाधन प्राप्त नहीं कर पाता
  • Deadlock के विपरीत, भूखा थ्रेड RUNNABLE अवस्था में रहता है और लोड कम होने पर निष्पादित हो सकता है
  • अनुचित लॉक (synchronized) और प्राथमिकताओं का गलत उपयोग Starvation के मुख्य कारण हैं
  • Fair Lock (true फ्लैग के साथ ReentrantLock) FIFO पहुंच क्रम सुनिश्चित करता है और स्टार्वेशन को पूरी तरह समाप्त करता है
  • लॉक-फ्री संरचनाएं (ConcurrentHashMap, AtomicReference) आर्किटेक्चर स्तर पर Starvation को समाप्त करती हैं
  • Thread Dump बार-बार कैप्चर के साथ और Java Flight Recorder Starvation के निदान के प्रभावी तरीके हैं
  • छोटे क्रिटिकल सेक्शन और ReadWriteLock उच्च-लोड सिस्टम में स्टार्वेशन की संभावना को कम करते हैं

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें