محتويات الدورة

Java / المتقدم / الدرس 15

الخيوط الافتراضية وحدود الإصدارات الصريحة

افهم الخيوط الافتراضية في Java21 أداة لتوسيع التزامن مع حفظ حدود القبول ونموذج الذاكرة وبدائل أساس17.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • تمييز الخيوط الافتراضية من تسريع المعالج.
  • ترجمة الأمثلة المحددة باستخدام Java21.
  • تقييد الموارد النادرة مستقلاً عن عدد الخيوط.

حدد ما يترجمه الأساس وما يتجاوزه

أصبحت الخيوط الافتراضية معيارية في Java21 بعد معاينات سابقة. لا تتاح Thread.ofVirtual وExecutors.newVirtualThreadPerTaskExecutor في Java17. تحدد هذه الوحدة أمثلتها الكاملة بـJava21 وتتحقق منها مستقلة، وتستهدف البرامج الأخرى --release17. لا يغير مشغل أحدث ما يقبله مترجم أقدم.

لا تمكّن المعاينة لإظهار واجهة غير مرتبطة ولا تنسب ميزة21 إلى17. يستطيع تطبيق17 استخدام منفذ خيوط منصة بحجم وقبول مقصودين. راع التوافق وسياسة الدعم والاعتماد والقياس عند الترقية، لا قصر المثال أو ادعاء الأحدث.

اشرح التنفيذ دون وعد بسرعة المعالج

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

يبدأ المثال عاملاً واحداً وينضم له ويعرض نتيجته ونوعه. يشرح الدلالة لا القياس، ولا آثار خارجية للعامل. يضمن join الاكتمال قبل الطباعة. لن يوضح إنشاء أعداد ضخمة العقد أكثر بل يضيف ضوضاء وكلفة.

java Java21: عامل افتراضي وإكمال صريح
public class Main {

 public static void main(String[] args) throws Exception {
var result=new java.util.concurrent.atomic.AtomicReference<String>();
Thread worker=Thread.ofVirtual().start(()->result.set("done"));
worker.join();
System.out.println(result.get());
System.out.println(worker.isVirtual());
 }
}
الناتج المتوقع
done
true

يتطلب Java21؛ ويكتمل العامل الافتراضي قبل الخرج ويضع النتيجة المصطنعة done.

قيّد المورد النادر مباشرة

لا يحد التنفيذ الافتراضي لكل مهمة عدد المرسَل. قيّد العمليات النادرة مستقلاً مثل سمافور لميزانية اتصال وحدد انتظار الطلبات ومواعيدها. لا تجمع الخيوط الافتراضية تقليداً لمجمع المنصة؛ فهي تمثل المهام لا مورداً نادراً يعاد استخدامه.

يكتسب المثال الثاني تصريحاً ويعيد قيمة ويحرره في finally. يطبق المنفذ AutoCloseable في هذا الإصدار فيصح عمر try-with-resources. يعود العدد المتاح إلى واحد. يفحص المثال الملكية لا سعة خدمة أو عدالة أو إلغاءً تحت حمل أو مكسب إنتاجية.

java Java21: مهمة بملكية مورد محدودة مستقلة
public class Main {

 public static void main(String[] args) throws Exception {
var permits=new java.util.concurrent.Semaphore(1);
try(var tasks=java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) {
 var future=tasks.submit(()->{
  permits.acquire();
  try { return 42; } finally { permits.release(); }
 });
 System.out.println(future.get());
}
System.out.println(permits.availablePermits());
 }
}
الناتج المتوقع
42
1

يتحرر التصريح حتى عند فشل الجسم؛ ويعيد النجاح42 والسعة إلى واحد.

اربط تحذير الأداء بالإصدار

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

تغير إصدارات لاحقة بعض التنفيذ فلا تحول قاعدة21 إلى نصيحة أبدية. راجع إصدار النشر. راجع ThreadLocal لأن ضرب بيانات كل خيط في مهام كثيرة مكلف. صغّر السياق ووضح التنظيف؛ لا يجعل الخيط الرخيص كل مراجعه رخيصة.

قس الخدمة قبل التبني وبعده

قارن أحمالاً متكافئة بالإنتاجية والتأخر الحاد والمعالج والكومة والحامل وحدود التوابع. ليس النجاح مكسباً يغرق القاعدة أو يزيد المهل. اختبر الإلغاء والفشل والإغلاق والسياق مع الطلب العادي. تبقى أخطاء المزامنة أخطاء تحت الخيوط الافتراضية.

تختلف مراقبتها باختلاف الإصدار؛ استخدم تفريغات وأحداث JDK المنشور. لا تتصل الدورة بعمليات مضبوطة ولا تدعي تسارع خدمة مقاساً. ينبغي أن تنتج الهجرة عقد سعة وعمر موثقاً بدليل ممثل ومسار رجوع إن لم يفد العمل.

الأخطاء الشائعة وإصلاحها

cannot find symbol: ofVirtual

لماذا يحدث؟
تُرجم مصدر21 بواجهة17.
كيف تصلحه؟
استخدم مترجم21 وهدفه أو بديل المنفذ الأساسي.
كيف تتجنب تكراره؟
سجل حدود الإصدار في البناء.

Virtual threads did not speed up a CPU loop

لماذا يحدث؟
خُلط توسع الانتظار بتسريع المعالج.
كيف تصلحه؟
قس الاختناق واختر توازي المعالج.
كيف تتجنب تكراره؟
قس العمل لا عدد الخيوط.

Downstream capacity was exhausted

لماذا يحدث؟
تجاوز الإنشاء الرخيص حدود القبول.
كيف تصلحه؟
قيّد المورد وحدد المهلة أو الرفض.
كيف تتجنب تكراره؟
اختبر الامتلاء والإلغاء بالميزانية.

اختبر فهمك

1. للخدمة20 اتصالاً وآلاف الطلبات الافتراضية. ماذا يبقى محدوداً؟

اعرض الحل المشروح

يظل وصول القاعدة بميزانية20 مع الطابور والمواعيد والذاكرة والموارد الأخرى. تبسط الخيوط انتظارها ولا تسمح بعمليات غير محدودة.

2. هل يترجم17 newVirtualThreadPerTaskExecutor بواسطة --enable-preview؟

اعرض الحل المشروح

لا؛ ليست واجهة17 ولا يعيدها علم المعاينة. ابن وشغل بـ21 أو استخدم تصميماً مدعوماً في17 بحدود عمر وقبول.

أهم ما تعلمته

  • الخيوط الافتراضية معيارية في21 وخارج أساس17.
  • توسع مهام الانتظار ولا تسرع المعالج.
  • تبقى قواعد القبول والتنظيف والذاكرة.

المراجع الرسمية