Coroutines — کلیدی تصورات، Kotlin میں Job اور Dispatchers

مصنف: IT Sectr اشاعت: 2026-03-16 مطالعے کا وقت: 8 منٹ

Coroutines (کوروٹینز) Kotlin میں غیر متوازن پروگرامنگ کے لیے ہلکے تھریڈ ہیں، جو kotlinx.coroutines لائبریری کے ذریعے دستیاب ہیں۔ JetBrains Kotlin Documentation, 2026 کے مطابق، Coroutines روایتی Thread کے برعکس، تھریڈ کو مسدود کیے بغیر فنکشن کے اجراء کو معطل کر سکتے ہیں۔ کوروٹینز ایک محدود تھریڈ پول پر چلتے ہیں، جو انہیں مقامی تھریڈ سے ہزار گنا ہلکا بناتا ہے۔ Kotlin Coroutines Android Jetpack، Retrofit، Room اور Android ماحولیاتی نظام کی دیگر مشہور لائبریریوں کے ساتھ مکمل طور پر ضم ہیں۔

اہم نکات

  • Coroutines — مسدودیت کے بغیر غیر متوازن کوڈ کے لیے ہلکے Kotlin تھریڈ
  • suspend فنکشن — ایک فنکشن جو تھریڈ کو مسدود کیے بغیر روک اور دوبارہ شروع ہو سکتا ہے
  • Dispatcher کوروٹین کے اجراء کے لیے تھریڈ پول کا تعین کرتا ہے
  • Job — منسوخی کی حمایت اور حالت کی ٹریکنگ کے ساتھ کوروٹین ڈسکرپٹر
  • CoroutineScope کوروٹینز کی زندگی کے دور اور مکمل ہونے پر ان کی منسوخی کا انتظام کرتا ہے

Kotlin کوروٹینز کیا ہیں

Coroutines Kotlin میں ایک غیر متوازن پروگرامنگ میکانزم ہے، جو kotlinx.coroutines لائبریری میں نافذ ہے۔ آپریٹنگ سسٹم تھریڈ کے برعکس، کوروٹینز کسی مخصوص تھریڈ سے منسلک نہیں ہوتے: وہ ایک تھریڈ پر رک سکتے ہیں اور دوسرے پر دوبارہ شروع ہو سکتے ہیں۔ ایک ہی تھریڈ کم سے کم اضافی لاگت کے ساتھ ہزاروں کوروٹینز پر سوئچ کر سکتا ہے۔

کوروٹینز Kotlin 1.3 (2018) میں ایک تجرباتی خصوصیت کے طور پر ظاہر ہوئے اور Kotlin 1.5 (2021) میں مستحکم ہو گئے۔ Coroutines async/await کی طرح کال بیک ہیل مسئلہ حل کرتے ہیں، لیکن زیادہ بھرپور API فراہم کرتے ہیں: چینل (Channel)، Flow، Job درجہ بندی میں استثناء ہینڈلنگ اور Android Lifecycle کے ساتھ براہ راست انضمام۔

JetBrains (2025) کے مطابق، ہر کوروٹین تقریباً 100 بائٹ میموری استعمال کرتا ہے جبکہ مقامی تھریڈ 1+ MB استعمال کرتا ہے۔ یہ OutOfMemoryError کے خطرے کے بغیر ایک ایپلیکیشن میں لاکھوں کوروٹینز چلانے کی اجازت دیتا ہے۔ کوروٹینز کی ہلکی پھلکی نوعیت ہی انہیں Android میں غیر متوازنیت کے لیے ترجیحی آلہ بناتی ہے۔

کوروٹینز پردے کے پیچھے کیسے کام کرتے ہیں

ہر Kotlin کوروٹین Continuation Passing Style (CPS) کے ذریعے ایک اسٹیٹ مشین میں مرتب ہوتا ہے۔ کمپائلر ہر suspend فنکشن میں ایک پوشیدہ Continuation پیرامیٹر شامل کرتا ہے۔ Continuation میں دوبارہ شروع کرنے کا نقطہ اور تمام مقامی متغیرات ہوتے ہیں۔ جب کوئی کوروٹین رکتا ہے، رن ٹائم Continuation محفوظ کرتا ہے، اور جب یہ دوبارہ شروع ہوتا ہے تو اسے Dispatcher پول کے کسی بھی دستیاب تھریڈ پر بحال کرتا ہے۔

suspend فنکشنز: روکنا اور دوبارہ شروع کرنا

suspend ایک Kotlin کلیدی لفظ ہے جو کسی فنکشن کو قابل معطل کے طور پر نشان زد کرتا ہے۔ ایسے فنکشن کو صرف دوسرے suspend فنکشن یا کوروٹین سے ہی کال کیا جا سکتا ہے۔ suspend فنکشن کے اندر، آپ کسی بھی ترتیب میں دوسرے suspend فنکشنز کو کال کر سکتے ہیں، اور ہر کال پوائنٹ ایک ممکنہ معطلی کا نقطہ ہے۔

میکانکس آسان ہے: جب کوئی suspend فنکشن دوسرے suspend فنکشن کو کال کرتا ہے، تو یہ اس نقطہ پر رک جاتا ہے، تھریڈ کو آزاد کرتا ہے۔ کال شدہ فنکشن مکمل ہونے کے بعد، رن ٹائم محفوظ کردہ مقام سے اجراء جاری رکھتا ہے۔ اسے باہمی تعاون سے منسوخی (cooperative cancellation) کہا جاتا ہے — کوئی تھریڈ مسدود نہیں ہوتا۔

  • معطلی — کوروٹین تھریڈ کو مسدود کیے بغیر آزاد کرتا ہے
  • دوبارہ شروع — کوروٹین وہیں سے جاری رہتا ہے جہاں وہ رکا تھا
  • تھریڈ — کوروٹین تھریڈ A پر رک کر تھریڈ B پر دوبارہ شروع ہو سکتا ہے
  • استثناء — مطابقت پذیر کوڈ کی طرح try/catch کے ذریعے سنبھالے جاتے ہیں

اہم: suspend فنکشن بطور ڈیفالٹ غیر متوازن نہیں ہے۔ اگر launch یا async استعمال نہ کیا جائے تو اجراء کا ترتیب سلسلہ وار رہتا ہے۔ suspend صرف فنکشن کو تھریڈ کو مسدود کیے بغیر رکنے اور کوروٹین سیاق و سباق کا حصہ بننے کی اجازت دیتا ہے۔ Continuation Passing Style ایک مرتب کرنے کا ماڈل ہے جہاں ہر suspend فنکشن ایک پوشیدہ Continuation کال بیک وصول کرتا ہے، اور کمپائلر معطلیوں اور دوبارہ شروع کرنے کے انتظام کے لیے ایک اسٹیٹ مشین تیار کرتا ہے۔

CoroutineScope اور ساختی ہم وقتی

CoroutineScope ایک سیاق و سباق ہے جو کوروٹینز کی زندگی کے دور کی وضاحت کرتا ہے۔ تمام کوروٹینز کو دائرہ کار کے اندر شروع کیا جانا چاہیے۔ جب کوئی دائرہ کار منسوخ ہوتا ہے (مثال کے طور پر، Activity ختم ہونے پر)، اس کے تمام ذیلی کوروٹینز خود بخود منسوخ ہو جاتے ہیں۔ یہ پس منظر کے کاموں کے رساو کو روکتا ہے۔ Android Jetpack ہر جزو کے لیے تیار دائرہ کار فراہم کرتا ہے: ViewModel کے لیے viewModelScope اور Activity/Fragment کے لیے lifecycleScope، جو متعلقہ جزو تباہ ہونے پر خود بخود منسوخ ہو جاتے ہیں۔

ساختی ہم وقتی (Structured Concurrency) ایک اصول ہے جو اس بات کی ضمانت دیتا ہے کہ ایک کوروٹین اس وقت تک مکمل نہیں ہوگا جب تک اس کے تمام ذیلی کوروٹینز مکمل نہ ہو جائیں۔ Job کا درجہ بندی ایک درخت بناتی ہے: ایک جڑ کوروٹین ایک والدین job بناتا ہے، بچے بچوں کے jobs بناتے ہیں۔ والدین job کی منسوخی تمام بچوں تک پھیل جاتی ہے۔ Structured Concurrency کوروٹینز اور تھریڈز کے درمیان ایک بنیادی فرق ہے۔

Scopeکہاں استعمال ہوتا ہےمنسوخی
GlobalScopeصرف ڈیمن کاموں کے لیےخود بخود منسوخ نہیں ہوتا
viewModelScopeAndroid ViewModelViewModel صاف ہونے پر
lifecycleScopeAndroid Activity/Fragmentlifecycle تباہ ہونے پر
coroutineScopesuspend فنکشن کے اندروالدین job منسوخ ہونے پر

غلطیوں کے انتظام کے لیے SupervisorJob

عام Job ایک ذیلی کوروٹین کے ناکام ہونے پر تمام ہم درجہ افراد کو منسوخ کر دیتا ہے۔ SupervisorJob ایک استثناء ہے: ایک ذیلی کوروٹین میں ناکامی دوسروں کو متاثر نہیں کرتی۔ یہ اس وقت اہم ہے جب متعدد آزاد کام متوازی طور پر انجام دیے جا رہے ہوں اور ان میں سے ایک دوسروں کو منسوخ کیے بغیر کریش ہو سکتا ہے۔

Dispatchers اور کوروٹین بلڈر

Dispatchers تعین کرتے ہیں کہ کوروٹینز کن تھریڈز پر انجام دی جائیں۔ Dispatchers.Main — مرکزی Android UI تھریڈ۔ Dispatchers.IO — مسدود کرنے والی کارروائیوں (نیٹ ورک، ڈسک) کے لیے ایک پول۔ Dispatchers.Default — CPU گہرے کاموں کے لیے۔ Dispatchers.Unconfined — موجودہ تھریڈ میں شروع ہوتا ہے لیکن اس پر رہنے کی ضمانت نہیں دیتا۔ صحیح Dispatcher کا انتخاب کارکردگی کے لیے اہم ہے: Default پر IO کام کمپیوٹ پول کو مسدود کر دے گا، جبکہ IO پر CPU کام غیر ضروری تھریڈز پیدا کرے گا۔

withContext — کوروٹین کے اندر Dispatcher تبدیل کرنے کے لیے ایک فنکشن۔ مثال کے طور پر، JSON پارس کرنے والا suspend فنکشن حساب کے لیے Dispatchers.Default پر جا سکتا ہے اور UI اپ ڈیٹ کے لیے Dispatchers.Main پر واپس آ سکتا ہے۔ withContext Android ڈویلپمنٹ میں سب سے زیادہ استعمال ہونے والا بلڈر ہے۔

تین اہم کوروٹین بلڈر

launch — کوروٹین شروع کرتا ہے، Job لوٹاتا ہے، نتیجہ واپس نہیں کرتا (fire-and-forget)۔ async — کوروٹین شروع کرتا ہے، Deferred لوٹاتا ہے جس سے await کے ذریعے نتیجہ حاصل کیا جا سکتا ہے۔ runBlocking — کوروٹین کو انجام دینے کے لیے موجودہ تھریڈ کو مسدود کرتا ہے (صرف ٹیسٹ اور main فنکشنز کے لیے)۔ بلڈر کا انتخاب منظر نامے پر منحصر ہے: launch واقعات اور اپ ڈیٹس کے لیے موزوں ہے، async نتیجہ والے کاموں کے لیے، runBlocking صرف ٹیسٹ یا داخلے کے مقامات کے لیے۔

Kotlin میں کوروٹینز کے ساتھ کوڈ کی مثالیں

آئیے تین عملی منظرناموں پر غور کریں: launch کے ساتھ ایک بنیادی کوروٹین، async کے ساتھ متوازی کال، اور SupervisorJob کے ساتھ غلطی کا انتظام۔

launch کے ساتھ کوروٹین شروع کرنا

viewModelScope.launch ViewModel سیاق و سباق میں کوروٹین شروع کرتا ہے۔ ViewModel صاف ہونے پر کوروٹین خود بخود منسوخ ہو جاتا ہے۔

kotlin
class ProfileViewModel : ViewModel() {
    fun loadUser() {
        viewModelScope.launch(Dispatchers.IO) {
            val user = api.fetchUser()
            withContext(Dispatchers.Main) {
                showUser(user)
            }
        }
    }
}

async کے ساتھ متوازی درخواستیں

coroutineScope async کے ساتھ تین درخواستیں متوازی طور پر شروع کرتا ہے۔ نتائج .await() کے ذریعے جمع کیے جاتے ہیں۔ اگر کوئی درخواست ناکام ہوتی ہے تو تمام منسوخ ہو جاتی ہیں۔

kotlin
suspend fun loadDashboard(): Dashboard = coroutineScope {
    val user = async { api.fetchUser() }
    val posts = async { api.fetchPosts() }
    val stats = async { api.fetchStats() }
    Dashboard(user.await(), posts.await(), stats.await())
}

SupervisorJob کے ساتھ غلطی کا انتظام

SupervisorJob ہر کوروٹین کو آزادانہ طور پر مکمل ہونے دیتا ہے۔ ایک درخواست میں غلطی دوسروں کو منسوخ نہیں کرتی۔

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try { api.fetchUsers() } catch (e: Exception) { log(e) }
}
scope.launch {
    try { api.fetchPosts() } catch (e: Exception) { log(e) }
}

کوروٹینز بمقابلہ تھریڈ: موازنہ اور منظرنامے

تھریڈ آپریٹنگ سسٹم کا ایک ابتدائی عنصر ہے۔ ہر تھریڈ کا اپنا اسٹیک (~1 MB) ہوتا ہے اور اسے بنانے اور سوئچ کرنے کے لیے سسٹم کال کی ضرورت ہوتی ہے۔ کوروٹینز زبان کا ایک ابتدائی عنصر ہے، OS سے منسلک نہیں۔ وہ حالت محفوظ کرنے کے لیے Continuation استعمال کرتے ہیں اور سسٹم کال کے بغیر رن ٹائم سطح پر سوئچ کرتے ہیں۔

  • میموری — تھریڈ ~1 MB، کوروٹین ~100 بائٹ۔ 10,000 گنا فرق
  • تخلیق — تھریڈ ~1 µs سسٹم کال، کوروٹین ~0.01 µs JVM سطح پر
  • سوئچنگ — تھریڈ ~0.1 µs (سسٹم کال)، کوروٹین ~0.001 µs (continuation)
  • زیادہ سے زیادہ — ہزاروں تھریڈ بمقابلہ لاکھوں کوروٹین فی ڈیوائس
  • منسوخی — تھریڈ کو بیرونی طور پر منسوخ نہیں کیا جا سکتا (متروک Thread.stop)، کوروٹین Job.cancel() کے ذریعے منسوخ کیا جا سکتا ہے

Google (2025) کے مطابق، تھریڈ کے بجائے کوروٹین استعمال کرنے سے Android ایپلیکیشنز میں پس منظر کے کاموں کے لیے میموری کی کھپت 90-95% کم ہو جاتی ہے۔ تمام جدید Android لائبریریاں (Retrofit, Room, WorkManager) suspend فنکشنز کے ذریعے بلٹ ان کوروٹین سپورٹ رکھتی ہیں۔ Ktor (JetBrains کا HTTP کلائنٹ فریم ورک) بھی مکمل طور پر کوروٹینز پر بنایا گیا ہے، جو کال بیک API کے بغیر ہر درخواست کے لیے suspend فنکشن فراہم کرتا ہے۔ Room DAO میں suspend فنکشنز کے ذریعے کوروٹینز کو سپورٹ کرتا ہے، جس سے مرکزی تھریڈ کو مسدود کیے بغیر ڈیٹا بیس کے سوالات انجام دیے جا سکتے ہیں۔

کوروٹینز کے بجائے تھریڈ کب استعمال کریں

تھریڈ JNI کے ذریعے مقامی کوڈ، طویل عرصے تک چلنے والی CPU گہری مسدود کرنے والی کالز (ویڈیو رینڈرنگ، سمیلیشنز) اور C لائبریریوں کے ساتھ انضمام کے لیے ضروری رہتے ہیں۔ باقی سب کے لیے — کوروٹینز۔

اکثر پوچھے گئے سوالات

کوروٹین تھریڈ سے کیسے مختلف ہے؟

کوروٹین کام کی ایک معطل اکائی ہے جو موجودہ تھریڈ پر انجام دی جاتی ہے۔ تھریڈ اپنے اسٹیک کے ساتھ ایک سسٹم وسیلہ ہے۔ کوروٹینز تھریڈ سے ہزاروں گنا ہلکے ہیں اور معطل ہونے پر وسائل کو مسدود نہیں کرتے۔

Dispatchers.IO کیا ہے اور یہ Default سے کیسے مختلف ہے؟

Dispatchers.IO مسدود کرنے والی I/O کارروائیوں (نیٹ ورک، فائلیں) کے لیے ڈیزائن کیا گیا ہے اور ضرورت پڑنے پر نئے تھریڈ بنا سکتا ہے۔ Dispatchers.Default CPU گہرے حسابات کے لیے ایک مقررہ سائز کا پول (CPU کورز کی تعداد) رکھتا ہے۔

چل رہے کوروٹین کو کیسے منسوخ کروں؟

Job.cancel() کوروٹین اور اس کے تمام بچوں کو منسوخ کرتا ہے۔ کوروٹین کے اندر منسوخی چیک کرنے کے لیے، ensureActive() استعمال کریں — یہ CancellationException پھینکتا ہے اگر کوروٹین منسوخ کر دیا گیا ہو۔

کیا کوروٹینز RxJava کے ساتھ استعمال کیے جا سکتے ہیں؟

ہاں — kotlinx-coroutines-rx3 لائبریری کے ذریعے۔ یہ Observable/Single کو suspend فنکشنز میں تبدیل کرنے اور flowable کے ذریعے واپس لانے کے لیے awaitSingle، awaitFirst اور دیگر فنکشنز فراہم کرتی ہے۔

کوروٹینز میں Flow کیا ہے؟

Flow ایک ٹھنڈا غیر متوازن ڈیٹا سٹریم ہے، جو کوروٹینز میں RxJava Observable کے برابر ہے۔ Flow ترتیب وار اقدار خارج کرتا ہے اور استثناء یا کامیابی کے ساتھ مکمل ہوتا ہے۔ یہ map، filter، catch اور دیگر آپریٹرز کو سپورٹ کرتا ہے۔

خلاصہ

  • Coroutines — Continuation Passing Style کے ذریعے غیر مسدود معطلی کے ساتھ ہلکے Kotlin تھریڈ
  • suspend — قابل معطل فنکشنز کو نشان زد کرنے کے لیے کلیدی لفظ
  • Dispatchers تھریڈ پول کا انتظام کرتے ہیں: Main، IO، Default بالترتیب
  • CoroutineScope کوروٹین کی زندگی کے دور کو ایک جزو (Activity, ViewModel) سے جوڑتا ہے
  • launch بغیر نتیجہ کے کوروٹین شروع کرتا ہے، async/await — نتیجہ کے ساتھ
  • Structured Concurrency ذیلی کوروٹینز کی درجہ بندی منسوخی کی ضمانت دیتا ہے
  • کوروٹینز بمقابلہ تھریڈ — کوروٹینز 10,000 گنا ہلکے اور Android کے لیے معیاری ہیں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں