मोबाइल डेवलपमेंट में Deadlock: यह क्या है, कारण और आपसी ब्लॉकिंग से बचने के तरीके

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

Deadlock (आपसी ब्लॉकिंग) एक ऐसी स्थिति है जिसमें दो या अधिक थ्रेड अन्य प्रतिभागियों द्वारा कब्जाए गए संसाधनों की रिहाई की अनिश्चित काल तक प्रतीक्षा करते हैं। Oracle Java Tutorials (2024) के अनुसार, Deadlock चक्रीय प्रतीक्षा में होता है जब प्रत्येक थ्रेड एक लॉक रखता है जो दूसरे थ्रेड के लिए आवश्यक है। विशेष डिटेक्शन टूल के बिना, Deadlock बिना दृश्य त्रुटियों के एप्लिकेशन निष्पादन को पूरी तरह से रोक देता है।

मुख्य बिंदु

  • Deadlock — थ्रेड का आपसी ब्लॉक होना जहां प्रत्येक थ्रेड दूसरे थ्रेड द्वारा कब्जाए गए संसाधन की प्रतीक्षा करता है
  • Coffman की चार शर्तें (Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait) Deadlock उत्पन्न होने के लिए आवश्यक हैं
  • Deadlock Starvation से भिन्न है क्योंकि थ्रेड अवरुद्ध नहीं हैं बल्कि चक्रीय निर्भरता में सक्रिय रूप से प्रतीक्षा कर रहे हैं
  • Thread Dump — JVM और Android Runtime में Deadlock का पता लगाने का प्राथमिक उपकरण
  • लॉक पदानुक्रम और संसाधन अधिग्रहण का एकीकृत क्रम — आपसी ब्लॉकिंग को रोकने का मुख्य तरीका

Deadlock क्या है?

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

मोबाइल डेवलपमेंट में, Deadlock विशेष रूप से महत्वपूर्ण है क्योंकि यह अपवाद या क्रैश नहीं करता। एप्लिकेशन उपयोगकर्ता क्रियाओं का जवाब देना बंद कर देता है (ANR — Application Not Responding), और एकमात्र समाधान प्रक्रिया को जबरन समाप्त करना है। Google (Android Performance Patterns, 2023) के अनुसार, Google Play Console में लगभग 15% ANR रिपोर्ट बैकग्राउंड थ्रेड में आपसी ब्लॉकिंग से संबंधित हैं।

Deadlock और अन्य concurrency समस्याओं के बीच मुख्य अंतर बाहरी हस्तक्षेप के बिना इसकी अपरिवर्तनीयता है। थ्रेड स्वयं संसाधन जारी नहीं करेंगे क्योंकि ऑपरेटिंग सिस्टम शेड्यूलर जबरन लॉक वापस नहीं ले सकता। यह Deadlock को Livelock से अलग करता है, जहां थ्रेड सक्रिय हैं लेकिन उपयोगी कार्य नहीं कर रहे हैं।

Deadlock की शर्तें

1971 में, Edward G. Coffman ने Deadlock उत्पन्न होने के लिए आवश्यक चार अनिवार्य शर्तें तैयार कीं। यदि उनमें से कम से कम एक अनुपस्थित है, तो आपसी ब्लॉकिंग असंभव है। ये शर्तें Coffman की शर्तों के रूप में जानी जाती हैं और सभी Deadlock रोकथाम एल्गोरिदम का आधार बनती हैं।

पारस्परिक बहिष्करण (Mutual Exclusion)

एक संसाधन केवल एक थ्रेड द्वारा किसी भी समय कब्जा किया जा सकता है। यदि कोई संसाधन कई थ्रेड द्वारा एक साथ पढ़ने की अनुमति देता है (जैसे ReadWriteLock रीड मोड में), तो Deadlock नहीं होता। यह शर्त Mutex और लॉक की प्रकृति से उत्पन्न होती है।

पकड़ो और प्रतीक्षा करो (Hold and Wait)

एक थ्रेड पहले से कब्जाए गए संसाधन को रखता है और साथ ही दूसरे संसाधन को प्राप्त करने की प्रतीक्षा करता है। यदि कोई थ्रेड अगले संसाधन का अनुरोध करने से पहले वर्तमान संसाधन को जारी कर सकता है (दो-चरण लॉकिंग के माध्यम से), तो Hold and Wait शर्त टूट जाती है। Android में, यह अक्सर तब प्रकट होता है जब कोई थ्रेड डेटाबेस लॉक रखता है और SharedPreferences लॉक प्राप्त करने का प्रयास करता है।

कोई जबरन बेदखली नहीं (No Preemption)

ऑपरेटिंग सिस्टम किसी थ्रेड से लॉक जबरन नहीं ले सकता। संसाधन तभी जारी होता है जब थ्रेड स्वयं इसे जारी करता है। कुछ सिस्टम में (जैसे SQLite WAL मोड), व्यक्तिगत संचालन के स्तर पर जबरन बेदखली लागू की जाती है, जो Deadlock के जोखिम को कम करती है।

चक्रीय प्रतीक्षा (Circular Wait)

थ्रेड की एक बंद श्रृंखला होती है, जिनमें से प्रत्येक श्रृंखला में अगले थ्रेड द्वारा रखे गए संसाधन की प्रतीक्षा करता है। उदाहरण के लिए, थ्रेड A संसाधन 1 रखता है और संसाधन 2 की प्रतीक्षा करता है, थ्रेड B संसाधन 2 रखता है और संसाधन 1 की प्रतीक्षा करता है। यह एकमात्र शर्त है जिसे डेवलपर आर्किटेक्चरल रूप से समाप्त कर सकता है — लॉक पदानुक्रम के माध्यम से। यदि सभी थ्रेड संसाधनों को सख्ती से परिभाषित वैश्विक क्रम में प्राप्त करते हैं, तो चक्र भौतिक रूप से असंभव है।

व्यवहार में, Android एप्लिकेशन में, Deadlock सबसे अधिक बार विभिन्न स्तरों के लॉक के अंतर्निहित प्रतिच्छेदन के कारण होता है: डेटाबेस लॉक (Room), SharedPreferences लॉक, और मेमोरी में कलेक्शन लॉक। इनमें से प्रत्येक लॉक विभिन्न घटकों द्वारा प्रबंधित किया जाता है, और अधिग्रहण क्रम के लिए केंद्रीकृत प्रोटोकॉल के बिना, डेवलपर्स अनजाने में चक्र बना देते हैं।

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

आइए आपसी ब्लॉकिंग का एक क्लासिक उदाहरण देखें — दो थ्रेड अलग-अलग क्रम में लॉक प्राप्त करते हैं। यदि पहला थ्रेड संसाधन A को लॉक करता है और B प्राप्त करने का प्रयास करता है, और दूसरा B को लॉक करता है और A प्राप्त करने का प्रयास करता है, तो Deadlock होता है।

kotlin
class DeadlockExample {
    private val lockA = Any()
    private val lockB = Any()

    fun operationA() {
        synchronized(lockA) {
            Thread.sleep(50)  // कार्य सिमुलेशन
            synchronized(lockB) {
                println("operationA पूर्ण हुआ")
            }
        }
    }

    fun operationB() {
        synchronized(lockB) {  // उल्टा क्रम
            Thread.sleep(50)
            synchronized(lockA) {
                println("operationB पूर्ण हुआ")
            }
        }
    }
}

fun main() {
    val ex = DeadlockExample()
    Thread { ex.operationA() }.start()
    Thread { ex.operationB() }.start()
    // एप्लिकेशन हमेशा के लिए हैंग हो जाएगा — Deadlock!
}

इस उदाहरण में, operationA lockA प्राप्त करता है, और operationB lockB प्राप्त करता है। फिर प्रत्येक दूसरा लॉक प्राप्त करने का प्रयास करता है — और दोनों अनिश्चित काल तक प्रतीक्षा करते हैं। प्रोग्राम बिना त्रुटि संदेश के हैंग हो जाता है। इसे ठीक करने का एकमात्र तरीका सभी विधियों में लॉक अधिग्रहण के समान क्रम की गारंटी देना है।

Deadlock बनाम Starvation बनाम Livelock

इन तीन concurrency समस्याओं को अक्सर भ्रमित किया जाता है, लेकिन उनके तंत्र और परिणाम मौलिक रूप से भिन्न हैं। Deadlock — पूर्ण विराम, Starvation — संसाधन की अनंत प्रतीक्षा, Livelock — सक्रिय निष्क्रियता। सही समाधान रणनीति चुनने के लिए अंतर को समझना महत्वपूर्ण है।

विशेषताDeadlockStarvationLivelock
थ्रेड की स्थितिअवरुद्ध (BLOCKED)तैयार (RUNNABLE)सक्रिय (RUNNABLE)
कार्य निष्पादननहींनहींहाँ, लेकिन बेकार
कारणचक्रीय प्रतीक्षाअनुचित शेड्यूलिंगगलत संघर्ष प्रबंधन
पता लगानाThread Dump, टाइमआउटप्रगति निगरानीपुनः प्रयास काउंटर

Starvation (भुखमरी) तब होती है जब शेड्यूलर दूसरों के पक्ष में कम प्राथमिकता वाले थ्रेड के निष्पादन को लगातार स्थगित करता है। Deadlock के विपरीत, थ्रेड अवरुद्ध नहीं है — वह निष्पादन के लिए तैयार है लेकिन CPU समय प्राप्त नहीं करता। Android में, एक विशिष्ट परिदृश्य कम प्राथमिकता वाला बैकग्राउंड थ्रेड है जो कभी निष्पादित नहीं होता यदि UI थ्रेड और Service थ्रेड लगातार सक्रिय हैं।

Livelock (सक्रिय ब्लॉकिंग) एक ऐसी स्थिति है जहां थ्रेड अवरुद्ध नहीं हैं लेकिन एक दूसरे की क्रियाओं पर अंतहीन प्रतिक्रिया करते हैं बिना उपयोगी कार्य किए। क्लासिक उदाहरण — दो लोग गलियारे में मिलते हैं और दोनों रास्ता देने की कोशिश करते हैं, एक ही दिशा में चलते हैं। Deadlock के विपरीत, Livelock में थ्रेड CPU की खपत करते हैं, डिवाइस की बैटरी खत्म करते हैं।

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

Thread Dump JVM और Android Runtime में आपसी ब्लॉकिंग का पता लगाने का प्राथमिक उपकरण है। डंप के दौरान, JVM स्वचालित रूप से मॉनिटर के बीच निर्भरता ग्राफ का विश्लेषण करता है और Deadlock चक्रों को चिह्नित करता है। Android Studio में, थ्रेड डंप Android Profiler या ADB Shell से kill -3 PID कमांड के माध्यम से प्राप्त किया जा सकता है।

रनटाइम पर स्वचालित Deadlock डिटेक्शन Watchdog टाइमर के माध्यम से कार्यान्वित किया जाता है। यदि कोई थ्रेड निर्दिष्ट टाइमआउट के भीतर कोई ऑपरेशन पूरा नहीं करता है, तो watchdog डंप शुरू करता है और Crash Reporting सिस्टम (Firebase Crashlytics, Sentry) को रिपोर्ट भेजता है। Sentry (Issue Resolution Report, 2024) के अनुसार, watchdog कॉन्फ़िगर करने से Deadlock निदान समय हफ्तों से कुछ घंटों तक कम हो जाता है।

डेवलपमेंट चरण में, JetBrains का ThreadSafe स्थैतिक विश्लेषक और Lock Checker मॉड्यूल के साथ Checker Framework प्रभावी हैं। ये उपकरण स्रोत कोड स्तर पर लॉक अधिग्रहण के क्रम का विश्लेषण करते हैं और संभावित चक्रों के बारे में चेतावनी देते हैं। इसके अतिरिक्त, Test-Driven Deadlock Detection की सिफारिश की जाती है — स्ट्रेस टेस्ट जो सैकड़ों थ्रेड में विभिन्न लॉक क्रमों के साथ संचालन चलाते हैं।

विशेष ध्यान Cooperative Deadlock Detection का है — एक विधि जहां थ्रेड वैश्विक रजिस्ट्री के माध्यम से प्राप्त लॉक के बारे में जानकारी का आदान-प्रदान करते हैं। यदि कोई थ्रेड संभावित चक्र का पता लगाता है, तो वह सभी संसाधन जारी करता है और ऑपरेशन दोहराता है। यह दृष्टिकोण वितरित सिस्टम (Apache ZooKeeper, Google Chubby) में उपयोग किया जाता है और Jetpack Sync जैसी लाइब्रेरी के माध्यम से धीरे-धीरे मोबाइल डेवलपमेंट में अपनाया जा रहा है।

आपसी ब्लॉकिंग रोकने के तरीके

लॉक पदानुक्रम (Lock Ordering)

सबसे विश्वसनीय तरीका पूरे एप्लिकेशन में लॉक अधिग्रहण का वैश्विक क्रम स्थापित करना है। यदि सभी थ्रेड हमेशा पहले छोटी संख्या वाला लॉक प्राप्त करते हैं, फिर बड़ी संख्या वाला, तो चक्रीय प्रतीक्षा (Circular Wait शर्त) असंभव है। बड़े प्रोजेक्ट में, क्रम दस्तावेजित किया जाता है और कोड समीक्षा के माध्यम से सत्यापित किया जाता है।

टाइमआउट के साथ TryLock

TryLock एक लॉकिंग विधि है जो थ्रेड को अनिश्चित काल तक ब्लॉक नहीं करती, बल्कि निर्दिष्ट समय के भीतर लॉक प्राप्त न होने पर false लौटाती है। Java में, यह ReentrantLock.tryLock(timeout, TimeUnit) के माध्यम से कार्यान्वित किया जाता है, Kotlin Coroutines में — टाइमआउट के साथ Mutex.withLock के माध्यम से। विफलता पर, थ्रेड सभी प्राप्त संसाधन जारी करता है और बाद में पुनः प्रयास करता है।

बैंकर एल्गोरिदम (Banker's Algorithm)

बैंकर एल्गोरिदम Edsger Dijkstra द्वारा प्रस्तावित Deadlock रोकथाम की एक सैद्धांतिक विधि है। यह संसाधन आवंटन को बैंक लेनदेन के रूप में मॉडल करता है: सिस्टम कोई संसाधन आवंटित नहीं करता यदि यह असुरक्षित स्थिति (deadlock) का कारण बन सकता है। व्यवहार में, थ्रेड की अधिकतम आवश्यकताओं को पहले से जानने की कठिनाई के कारण एल्गोरिदम शायद ही कभी मोबाइल डेवलपमेंट में उपयोग किया जाता है, लेकिन इसके सिद्धांत SQLite डेटाबेस और फ़ाइल सिस्टम में उपयोग किए जाते हैं।

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

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

नहीं, आपसी ब्लॉकिंग के लिए कम से कम दो थ्रेड आवश्यक हैं। एकल-थ्रेडेड कोड में, सभी ऑपरेशन अनुक्रमिक रूप से निष्पादित होते हैं, इसलिए चक्रीय प्रतीक्षा असंभव है। हालांकि, फ़ाइल लॉक या इंटरप्रोसेस सेमाफोर का उपयोग करते समय Deadlock प्रक्रियाओं के बीच हो सकता है।

Kotlin Coroutines में Deadlock थ्रेड में Deadlock से कैसे भिन्न है?

Coroutines में, Deadlock सस्पेंड फ़ंक्शन (suspend) के स्तर पर होता है और OS थ्रेड को ब्लॉक नहीं करता, जिससे यह कम ध्यान देने योग्य होता है। kotlinx.coroutines का Mutex एक सस्पेंडिंग लॉक है — यह थ्रेड को ब्लॉक नहीं करता, लेकिन coroutine निष्पादित नहीं होता। पता लगाने के लिए, kotlinx-coroutines-debug मॉड्यूल से DebugProbes का उपयोग करें।

Android पर SQLite में Deadlock क्या है?

SQLite Deadlock तब होता है जब डेटाबेस के दो कनेक्शन अलग-अलग क्रम में लेनदेन निष्पादित करने का प्रयास करते हैं। SQLite ऐसी स्थितियों का पता लगाता है और SQLITE_BUSY या SQLITE_LOCKED त्रुटि कोड लौटाता है। Android में, एकल डेटाबेस इंस्टेंस और @Transaction के माध्यम से लेनदेन के साथ Room का उपयोग करने की सिफारिश की जाती है, जो अंतर-कनेक्शन Deadlock को समाप्त करता है।

Android Deadlock का पता कैसे लगाता है?

Android Runtime में एक अंतर्निहित Deadlock डिटेक्टर है जो ANR (Application Not Responding) उत्पन्न होने पर चलता है। सिस्टम एप्लिकेशन के सभी थ्रेड के Thread Dump का विश्लेषण करता है और आपसी ब्लॉकिंग को चिह्नित करता है। परिणाम /data/anr/traces.txt और Google Play Console के ANR Reports अनुभाग में उपलब्ध है।

यदि प्रोडक्शन में Deadlock मिले तो क्या करें?

सबसे पहले, एप्लिकेशन के सभी थ्रेड का Thread Dump प्राप्त करें। विश्लेषण करें कि प्रत्येक थ्रेड कौन से लॉक रखता है और कौन से प्राप्त करने का प्रयास कर रहा है। समय सीमा पार होने पर स्वचालित डंप के साथ Watchdog टाइमर लागू करें। ठीक करने के बाद, पुनरावृत्ति को रोकने के लिए CI पाइपलाइन में ThreadSafety lint नियम जोड़ें।

सारांश

  • Deadlock — आपसी ब्लॉकिंग जहां थ्रेड एक दूसरे द्वारा रखे गए संसाधनों की अनंत प्रतीक्षा करते हैं
  • Coffman की चार शर्तें (Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait) Deadlock के लिए आवश्यक हैं
  • Thread Dump — JVM और Android Runtime में आपसी ब्लॉकिंग का पता लगाने की मानक विधि
  • एकीकृत वैश्विक क्रम के साथ लॉक पदानुक्रम चक्रीय प्रतीक्षा शर्त को पूरी तरह समाप्त करता है
  • टाइमआउट के साथ TryLock अनंत प्रतीक्षा को रोकता है और थ्रेड को संसाधन अनुपलब्धता को सही ढंग से संभालने की अनुमति देता है
  • Deadlock बनाम Starvation — Deadlock में थ्रेड अवरुद्ध हैं, Starvation में निष्पादन के लिए तैयार हैं लेकिन CPU नहीं मिलता
  • Watchdog टाइमर और स्थैतिक विश्लेषक (ThreadSafe, Checker Framework) — CI/CD में Deadlock से बुनियादी सुरक्षा

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

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

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

यह भी पढ़ें