0Pricing
Java Academy · درس

الخيوط المنصّية مقابل الافتراضية

متى يكون كل نوع مناسبًا

الخيوط المنصّية مقابل الافتراضية درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

نوعا الخيوط

أصبح لدى Java الآن نوعان من الخيوط. خيوط المنصة هي الأغلفة التقليدية حول خيوط نظام التشغيل. أما الخيوط الافتراضية فهي خفيفة الوزن وتديرها JVM.

ومعرفة الوقت المناسب لاستخدام كل نوع هي جوهر كتابة شيفرة Java متزامنة وقابلة للتوسع.

إنشاء خيط منصة

تنشئ خيط منصة باستخدام Thread.ofPlatform()، وهو النظير لـ Thread.ofVirtual().

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread p = Thread.ofPlatform().name("native-worker").start(() ->
            System.out.println("Platform? " + !Thread.currentThread().isVirtual()));
        p.join();
    }
}

مقارنة التكلفة

خيوط المنصة مرتفعة التكلفة:

  • مكدس محجوز بحجم يقارب 1 MB لكل خيط
  • بطيئة الإنشاء
  • محدودة ببضعة آلاف

أما الخيوط الافتراضية فمنخفضة التكلفة: مكدس أولي صغير، وإنشاء سريع، وإمكانية إنشاء الملايين منها.

العمل المقيّد بالإدخال والإخراج

إذا كانت مهمتك تقضي معظم وقتها في الانتظار على الشبكة أو القرص أو قاعدة البيانات، فستتفوق الخيوط الافتراضية بفارق كبير.

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

العمل المقيّد بالمعالج

في العمليات الحسابية البحتة التي لا تتعرض للحظر مطلقًا، لا توفر الخيوط الافتراضية أي زيادة في السرعة. فعدد الأنوية هو العامل المحدِّد.

في هذه الحالة، تكون الأداة المناسبة هي تجمّع ثابت بحجم يتناسب مع عدد المعالجات.

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws Exception {
        int cores = Runtime.getRuntime().availableProcessors();
        try (ExecutorService cpu = Executors.newFixedThreadPool(cores)) {
            Future<Long> f = cpu.submit(() -> {
                long s = 0;
                for (long i = 0; i < 1_000_000L; i++) s += i;
                return s;
            });
            System.out.println("Cores: " + cores + ", sum: " + f.get());
        }
    }
}

محاكاة الحظر

يوضح هذا المقتطف تشغيل عدد كبير من الخيوط الافتراضية التي تكون في حالة نوم متزامنة، بوصف ذلك بديلًا عن عمليات الإدخال والإخراج المحظورة. حاول أن تتخيل 10,000 خيط منصة تفعل الشيء نفسه.

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args) {
        AtomicInteger done = new AtomicInteger();
        try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 10_000; i++) {
                exec.submit(() -> {
                    try { Thread.sleep(50); } catch (InterruptedException e) {}
                    done.incrementAndGet();
                });
            }
        }
        System.out.println("Finished blocking tasks: " + done.get());
    }
}

حالة daemon

تكون الخيوط الافتراضية دائمًا خيوط daemon، ولا يمكن جعلها غير daemon. أما خيوط المنصة، فترث افتراضيًا حالة daemon من الخيط الذي أنشأها، لكن يمكن ضبط هذه الحالة صراحةً.

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread v = Thread.ofVirtual().unstarted(() -> {});
        Thread p = Thread.ofPlatform().unstarted(() -> {});
        System.out.println("virtual daemon: " + v.isDaemon());
        System.out.println("platform daemon: " + p.isDaemon());
    }
}

تُتجاهل الأولويات

تُبلغ الخيوط الافتراضية دائمًا عن أولوية تساوي NORM_PRIORITY، ولا يكون لضبط الأولوية أي تأثير. تتولى JVM الجدولة، وليس مُجدول نظام التشغيل.

public class Main {
    public static void main(String[] args) {
        Thread v = Thread.ofVirtual().unstarted(() -> {});
        v.setPriority(Thread.MAX_PRIORITY);
        System.out.println("Priority is still: " + v.getPriority());
    }
}

إرشادات الاختيار

قاعدة عملية تقريبية:

  • هل لديك مهام كثيرة تنتظر عمليات الإدخال والإخراج؟ استخدم الخيوط الافتراضية.
  • هل لديك عمليات حسابية كثيفة يحدّها المعالج؟ استخدم تجمّعًا ثابتًا من خيوط المنصة.
  • هل تحتاج إلى ضبط الخيوط على مستوى نظام التشغيل، مثل الأولوية أو الارتباط بمعالج؟ استخدم خيوط المنصة.

يمكنها التعايش

ليس عليك اختيار نوع واحد للبرنامج بأكمله. يستخدم التطبيق المعتاد الخيوط الافتراضية لمعالجة الطلبات، وتجمّعًا صغيرًا من خيوط المنصة للأجزاء المكثفة حسابيًا.

يشترك النوعان في واجهة API نفسها الخاصة بـ Thread، لذا فإن مزجهما سلس.

نصيحة للترحيل

عند نقل خدمة كثيفة الاستخدام لعمليات الإدخال والإخراج، يتمثل أصغر تغيير في تبديل المنفّذ: استبدل التجمّع الثابت أو المخزّن مؤقتًا بـ newVirtualThreadPerTaskExecutor().

انتبه فقط إلى التثبيت وإساءة استخدام ThreadLocal، إذ سيتناول الدرس التالي هذين الموضوعين.

اختبار سريع

اختر نوع أعباء العمل الذي تحقق فيه الخيوط الافتراضية أوضح فائدة.

مراجعة

قارنت بين نموذجي الخيوط:

  • خيوط المنصة: مرتفعة التكلفة، مدعومة بخيوط نظام التشغيل، ومناسبة للأعمال المقيّدة بالمعالج ولضبط نظام التشغيل
  • الخيوط الافتراضية: منخفضة التكلفة، تديرها JVM، ودائمًا من نوع daemon، ومناسبة للتزامن المقيّد بالإدخال والإخراج
  • يمكنها التعايش وتشترك في واجهة API نفسها

التالي: مخاطر التثبيت وThreadLocals.

الأسئلة الشائعة

هل درس «الخيوط المنصّية مقابل الافتراضية» مجاني؟

نعم — نص درس «الخيوط المنصّية مقابل الافتراضية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «الخيوط المنصّية مقابل الافتراضية»؟

متى يكون كل نوع مناسبًا تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الخيوط المنصّية مقابل الافتراضية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ما الخيوط الافتراضية
  2. إنشاء الخيوط الافتراضية
  3. الخيوط المنصّية مقابل الافتراضية
  4. المزالق: التثبيت وThreadLocals
← العودة إلى Java Academy