Kotlin التزامن: الخيوط، الكوروتينات و async/await للمبتدئين

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

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

ابدأ الدورة

Kotlin vs Python: من يغلب؟ معركة التزامن

\n\n

إذا كنت تقرأ هذه المادة على PythonLib، فمن المحتمل أنك على دراية بـ Python و GIL (قفل المترجم العام) الذي يحول تعدد الخيوط إلى صداع. تكتب threading، وتأمل في زيادة السرعة، لكنك تحصل على... كود متزامن بنكهة الأقفال. مألوف؟

\n\n

مرحباً بك في عالم Kotlin! إنها لغة قررت: "لنجعل التزامن مريحاً وسريعاً وبدون ألم". في هذه المقالة، سنستعرض ثلاثة أساليب للتزامن في Kotlin: الخيوط التقليدية، الكوروتينات الحديثة، والثنائي القوي async/await. ستتعلم كيفية كتابة كود غير متزامن لا يفجر عقلك، ولماذا Kotlin خيار ممتاز لتطوير backend وتطبيقات Android.

\n\n

1. الخيوط في Kotlin: صديق قديم أفضل من جديدين؟

\n\n

لنبدأ بالأساسيات. الخيوط (threads) في Kotlin هي نفس الخيوط في Java. يعمل Kotlin على JVM، لذا لديك إمكانية الوصول إلى كل قوة java.lang.Thread. لكن لنكن صادقين: الخيوط تشبه القيادة بسيارة بدون وسائد هوائية. تعمل، لكنها مخيفة.

\n\n

كيف تنشئ خيطاً في Kotlin؟

\n\n

أبسط طريقة:

\n\n
fun main() {\n    thread {\n        println("مرحباً من الخيط: ${Thread.currentThread().name}")\n    }\n    println("الخيط الرئيسي: ${Thread.currentThread().name}")\n}
\n\n

يبدو مألوفاً، أليس كذلك؟ لكن هناك فارق: الخيوط ثقيلة. كل خيط هو مورد نظام منفصل. إذا أنشأت 10,000 خيط، فسيؤدي ذلك إما إلى تعطل برنامجك مع OutOfMemoryError أو سيبطئ مثل كمبيوتر قديم يعمل بنظام Windows 95.

\n\n

مشاكل الخيوط:

\n
    \n
  • استهلاك عالي للذاكرة — كل خيط يحجز مكدساً (~1 ميجابايت).
  • \n
  • صعوبة المزامنة — الأقفال، حالات الجمود، حالات السباق. تذكر synchronized في Java وابكِ.
  • \n
  • تبديل السياق — نظام التشغيل يضيع وقتاً في التبديل بين الخيوط.
  • \n
\n\n

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

\n\n

2. الكوروتينات في Kotlin: خفيفة كالريشة

\n\n

الكوروتينات (coroutines) هي "خيوط معززة بالمنشطات". إنها غير مرتبطة بخيوط النظام ويمكن تنفيذها على خيط واحد، مع التبديل بين المهام دون تدخل نظام التشغيل. يبدو معقداً؟ في الواقع، إنها بسيطة وأنيقة.

\n\n

أول كوروتين

\n\n

للعمل مع الكوروتينات، ستحتاج إلى التبعية kotlinx-coroutines-core. لكن إذا كنت تستخدم Kotlin 1.3+، فهي مدمجة بالفعل.

\n\n
import kotlinx.coroutines.*\n\nfun main() = runBlocking {\n    launch {\n        delay(1000L)\n        println("العالم بعد التأخير!")\n    }\n    println("مرحباً،")\n}
\n\n

ماذا يحدث هنا؟

\n
    \n
  • runBlocking — يحجب الخيط الرئيسي حتى تنتهي جميع الكوروتينات بداخله. للتعلم جيد، للإنتاج استخدمه بحذر.
  • \n
  • launch — يبدأ كوروتيناً جديداً. لا يحجب الخيط، بل يتوقف مؤقتاً عند delay.
  • \n
  • delay — مشابه لـ Thread.sleep()، لكنه غير محجب. الكوروتين ببساطة "ينام" ويحرر الخيط لمهام أخرى.
  • \n
\n\n

النتيجة: أولاً يُطبع "مرحباً،"، وبعد ثانية يُطبع "العالم بعد التأخير!". بدون أقفال، بدون خيوط إضافية.

\n\n

لماذا الكوروتينات أفضل من الخيوط؟

\n
    \n
  • خفيفة الوزن — مليون كوروتين؟ بسهولة! إنها لا تنشئ خيوطاً منفصلة.
  • \n
  • التعليق (suspension) — يمكن للكوروتين التوقف في أي لحظة والاستمرار لاحقاً.
  • \n
  • التزامن المنظم — تعيش الكوروتينات في نطاق (scope) وتُلغى تلقائياً إذا انتهى النطاق.
  • \n
\n\n

الموزعون (Dispatchers

المدونات

توصيات الكتب