التزامن في Java: من الخيوط التقليدية إلى الجوروتينات و async/await
\n\nJava هي لغة تعمل مع مهام متعددة في وقت واحد منذ نشأتها. لكن العالم لا يقف ساكنًا. اليوم سنتحدث عن التزامن في Java — من الخيوط التقليدية (Thread) إلى الخيوط الافتراضية (الجوروتينات من Project Loom) والنهج غير المتزامن مع async/await (على سبيل المثال CompletableFuture).
\n\nإذا كنت تكتب بلغة Java وتريد ألا "يتباطأ" خادمك تحت الحمل، مع بقاء الكود قابلًا للقراءة، فهذه المقالة لك. هيا بنا!
\n\nلماذا التزامن مهم لمطور Java الحديث؟
\n\nتخيل أن موقعك يعالج 10,000 طلب في الثانية. إذا تم تنفيذ كل طلب بشكل تسلسلي، سينتظر المستخدمون إلى الأبد. التزامن في Java يسمح بتنفيذ مهام متعددة "في وقت واحد"، باستخدام موارد المعالج بكفاءة.
\n\nالتطبيقات الحديثة ليست مجرد CRUD. إنها خدمات مصغرة، معالجة تدفقات البيانات، WebSocket، تحليلات فورية. بدون فهم تعدد الخيوط في Java، فإنك تخاطر بكتابة كود إما أن يتعطل مع OutOfMemoryError أو يعمل ببطء شديد.
\n\nالمستوى 1: الخيوط التقليدية (Thread) — الأساس
\n\nالخيط في Java هو أبسط تجريد لتنفيذ الكود بالتوازي. كل خيط هو "عملية خفيفة الوزن" منفصلة داخل نظام التشغيل.
\n\nإليك أبسط مثال لإنشاء خيط:
\n\npublic class ThreadExample {\n public static void main(String[] args) {\n Thread thread = new Thread(() -> {\n for (int i = 0; i < 5; i++) {\n System.out.println("مرحبًا من الخيط: " + i);\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n Thread.currentThread().interrupt();\n }\n }\n });\n thread.start();\n System.out.println("الخيط الرئيسي يواصل العمل");\n }\n}\n\nالمزايا:
\n- \n
- سهولة الإنشاء — new Thread(() -> { ... }).start(); \n
- تحكم مباشر في دورة الحياة. \n
العيوب:
\n- \n
- إنشاء الخيط عملية مكلفة (تكاليف إضافية على المكدس، تبديل السياق). \n
- حدود العدد: 10,000 خيط قد تقتل JVM الخاصة بك. \n
- صعوبة المزامنة: deadlock, race condition. \n
النهج التقليدي جيد للمهام الصغيرة، لكنه غير مناسب لتطبيقات الحمل العالي. هنا تأتي الخيوط الافتراضية في Java للإنقاذ.
\n\nالمستوى 2: الخيوط الافتراضية (Project Loom) — الجوروتينات في Java
\n\nإذا كنت قد سمعت عن الجوروتينات في Go، فإن الخيوط الافتراضية في Java هي تقريبًا نفس الشيء. ظهرت في Java 21 (Project Loom) وتغير قواعد اللعبة تمامًا.
\n\nالخيوط الافتراضية هي خيوط "خفيفة الوزن" تديرها JVM، وليس نظام التشغيل. يمكن إنشاء الملايين منها، وتستهلك حدًا أدنى من الذاكرة.
\n\nمثال على إنشاء خيط افتراضي:
\n\npublic class VirtualThreadExample {\n public static void main(String[] args) throws InterruptedException {\n // إنشاء 100,000 خيط افتراضي\n var threads = new Thread[100_000];\n for (int i = 0; i < threads.length; i++) {\n threads[i] = Thread.startVirtualThread(() -> {\n // محاكاة عمل مع I/O محظور\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n Thread.currentThread().interrupt();\n }\n });\n }\n for (Thread t : threads) {\n t.join();\n }\n System.out.println("جميع الخيوط الافتراضية اكتملت!");\n }\n}\n\nمذهل، أليس كذلك؟