الخيوط، الجوروتينات و async/await في Java: كتابة كود متزامن بشكل صحيح

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

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

ابدأ الدورة

التزامن في Java: من الخيوط التقليدية إلى الجوروتينات و async/await

\n\n

Java هي لغة تعمل مع مهام متعددة في وقت واحد منذ نشأتها. لكن العالم لا يقف ساكنًا. اليوم سنتحدث عن التزامن في 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\n
public 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
    \n
  • إنشاء الخيط عملية مكلفة (تكاليف إضافية على المكدس، تبديل السياق).
  • \n
  • حدود العدد: 10,000 خيط قد تقتل JVM الخاصة بك.
  • \n
  • صعوبة المزامنة: deadlock, race condition.
  • \n
\n\n

النهج التقليدي جيد للمهام الصغيرة، لكنه غير مناسب لتطبيقات الحمل العالي. هنا تأتي الخيوط الافتراضية في Java للإنقاذ.

\n\n

المستوى 2: الخيوط الافتراضية (Project Loom) — الجوروتينات في Java

\n\n

إذا كنت قد سمعت عن الجوروتينات في Go، فإن الخيوط الافتراضية في Java هي تقريبًا نفس الشيء. ظهرت في Java 21 (Project Loom) وتغير قواعد اللعبة تمامًا.

\n\n

الخيوط الافتراضية هي خيوط "خفيفة الوزن" تديرها JVM، وليس نظام التشغيل. يمكن إنشاء الملايين منها، وتستهلك حدًا أدنى من الذاكرة.

\n\n

مثال على إنشاء خيط افتراضي:

\n\n
public 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

مذهل، أليس كذلك؟

المدونات

توصيات الكتب