التزامن وتعدد الخيوط في Kotlin: من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التزامن وتعدد الخيوط في Kotlin: من الألف إلى الياء



تتطلب التطبيقات الحديثة بشكل متزايد تنفيذ مهام متعددة في وقت واحد. في Kotlin، كما هو الحال في لغات JVM الأخرى، يتم تنفيذ تعدد الخيوط تقليديًا من خلال الفئة Thread. ومع ذلك، تقدم اللغة أداة أكثر قوة وأناقة - الكوروتينات (coroutines). في هذه المقالة، سنغطي جميع جوانب التزامن وتعدد الخيوط في Kotlin: من المفاهيم الأساسية إلى التقنيات المتقدمة.



1. أساسيات تعدد الخيوط: Thread و Runnable



لنبدأ بالنهج الكلاسيكي. في Kotlin، كما في Java، يمكنك إنشاء خيط مباشرة:



fun main() {    val thread = Thread {        for (i in 1..5) {            println("الخيط: $i")            Thread.sleep(500)        }    }    thread.start()    println("تم إنهاء الخيط الرئيسي")}


ومع ذلك، فإن الإدارة اليدوية للخيوط لها عيوب:

  • تكاليف عامة عالية - إنشاء الخيوط وتدميرها مكلف.
  • صعوبة المزامنة - من السهل الوقوع في حالة تسابق.
  • عدد محدود من الخيوط - يمكن للنظام إنشاء عدد محدود فقط من الخيوط.


لمزامنة الوصول إلى البيانات المشتركة، يتم استخدام الكلمة المفتاحية synchronized أو أقفال ReentrantLock:



class Counter {    private var count = 0    @Synchronized    fun increment() {        count++    }}


2. الكوروتينات - نهج حديث للتزامن



الكوروتينات هي خيوط خفيفة الوزن تحل مشاكل تعدد الخيوط التقليدي. إنها غير مرتبطة بخيوط النظام ويمكن تنفيذها على خيط واحد، مع التبديل بين المهام.



2.1. أول كوروتين



للعمل مع الكوروتينات، تحتاج إلى إضافة التبعية org.jetbrains.kotlinx:kotlinx-coroutines-core. مثال على أبسط كوروتين:



import kotlinx.coroutines.*

fun main() = runBlocking { launch { delay(1000L) println("العالم!") } println("مرحبًا،")}


هنا runBlocking هو جسر بين الكود العادي والكوروتينات. launch يبدأ كوروتين جديد، و delay هو نظير Thread.sleep()، لكنه لا يحجب الخيط.



2.2. دوال Suspend



الكلمة المفتاحية suspend تسمح بإيقاف تنفيذ الدالة مؤقتًا دون حجب الخيط:



suspend fun fetchData(): String {    delay(2000L) // محاكاة طلب شبكة    return "تم استلام البيانات"}

fun main() = runBlocking { val result = async { fetchData() } println("انتظار...") println(result.await())}


2.3. التزامن المنظم



يدعم Kotlin التزامن المنظم - يتم إنهاء جميع الكوروتينات الفرعية تلقائيًا قبل إنهاء الكوروتين الأب:



fun main() = runBlocking {    coroutineScope {        launch {            delay(1000L)            println("المهمة 1")        }        launch {            delay(500L)            println("المهمة 2")        }    }    println("تم إنهاء جميع المهام")}


3. تقنيات متقدمة: Channel و Flow و Dispatchers



3.1. القنوات (Channel)



تسمح القنوات بتبادل البيانات بين الكوروتينات. إنها تشبه قائمة الانتظار:



fun main() = runBlocking {    val channel = Channel<Int>()        launch {        for (i in 1..5) {            channel.send(i * i)        }        channel.close()    }        for (value in channel) {        println(value)    }}


3.2. Flow - تدفقات البيانات الباردة



Flow هو تدفق تفاعلي يصدر القيم عند الطلب:



fun simpleFlow(): Flow<Int> = flow {    for (i in 1..3) {        delay(                

المدونات

توصيات الكتب