"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > استكشاف التثبيت في آلية الخيط الافتراضي لـ JVM

استكشاف التثبيت في آلية الخيط الافتراضي لـ JVM

تم النشر بتاريخ 2024-11-08
تصفح:989

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

المواضيع الافتراضية: نهج التزامن خفيف الوزن

سلاسل Java الافتراضية هي كيانات مُدارة تعمل فوق سلاسل عمليات نظام التشغيل الأساسي (سلاسل الناقل). إنها توفر طريقة أكثر فعالية للتعامل مع التزامن مقارنةً بإنشاء العديد من سلاسل عمليات نظام التشغيل، حيث إنها تتحمل حملًا أقل. يقوم JVM بتعيين الخيوط الافتراضية لخيوط الناقل بشكل ديناميكي، مما يسمح باستخدام أفضل للموارد.

  • تتم إدارتها بواسطة JVM: على عكس سلاسل عمليات نظام التشغيل التي تتم إدارتها مباشرة بواسطة نظام التشغيل، يتم إنشاء سلاسل العمليات الافتراضية وجدولتها بواسطة Java Virtual Machine (JVM). وهذا يسمح بالتحكم والتحسين الدقيق داخل بيئة JVM.

  • تقليل الحمل: يؤدي إنشاء وإدارة سلاسل المحادثات الافتراضية إلى تحمل حمل أقل بكثير مقارنة بسلاسل عمليات نظام التشغيل. وذلك لأن JVM يمكنه إدارة مجموعة أكبر من سلاسل العمليات الافتراضية بكفاءة، وذلك باستخدام عدد أقل من سلاسل عمليات نظام التشغيل الأساسية.

  • التوافق مع الكود الموجود: تم تصميم سلاسل الرسائل الافتراضية بحيث تتكامل بسلاسة مع كود Java الموجود. يمكن استخدامها جنبًا إلى جنب مع سلاسل عمليات نظام التشغيل التقليدية والعمل ضمن التركيبات المألوفة مثل Executor وExecutorService لإدارة المتزامنة.

الشكل أدناه يوضح العلاقة بين المواضيع الافتراضية وخيوط المنصة:

Exploring Pinning in JVM


التثبيت: عندما يتعطل مؤشر ترابط افتراضي

يحدث التثبيت عندما يصبح الخيط الظاهري مرتبطًا بخيط الناقل الخاص به. وهذا يعني بشكل أساسي أنه لا يمكن استباق الخيط الظاهري (التبديل إلى خيط ناقل آخر) أثناء وجوده في حالة مثبتة. فيما يلي السيناريوهات الشائعة التي تؤدي إلى التثبيت:

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

مثال الكود:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

  public static void main(String[] args) throws InterruptedException {

    final Counter counter = new Counter();

    Runnable task = () -> {
      for (int i = 0; i 



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

عندما يواجه مؤشر ترابط افتراضي نقطة حظر، يتم نقل حالته إلى PARKING. تتم الإشارة إلى انتقال الحالة هذا عن طريق استدعاء طريقة VirtualThread.park():

// JDK core code
void park() {
  assert Thread.currentThread() == this;
  // complete immediately if parking permit available or interrupted
  if (getAndSetParkPermit(false) || interrupted)
    return;
  // park the thread
  setState(PARKING);
  try {
    if (!yieldContinuation()) {
      // park on the carrier thread when pinned
      parkOnCarrierThread(false, 0);
    }
  } finally {
    assert (Thread.currentThread() == this) && (state() == RUNNING);
  }
}

دعونا نلقي نظرة على نموذج التعليمات البرمجية لتوضيح هذا المفهوم:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

  public static void main(String[] args) {

    Counter counter = new Counter();

    Runnable task = () -> {
      for (int i = 0; i 



  • الطرق الأصلية/الوظائف الخارجية: قد يؤدي تشغيل الأساليب الأصلية أو الوظائف الخارجية أيضًا إلى التثبيت. قد لا يتمكن JVM من إدارة حالة مؤشر الترابط الظاهري بكفاءة أثناء هذه العمليات.

مراقبة التثبيت باستخدام -Djdk.tracePinnedThreads=full

العلامة -Djdk.tracePinnedThreads=full هي وسيطة بدء تشغيل JVM التي توفر معلومات تتبع مفصلة حول تثبيت مؤشر الترابط الظاهري. عند تمكينه، فإنه يسجل أحداثًا مثل:

  • معرف الموضوع الافتراضي المتضمن في التثبيت
  • معرف مؤشر الترابط الناقل الذي تم تثبيت مؤشر الترابط الظاهري عليه
  • يشير تتبع المكدس إلى قسم التعليمات البرمجية الذي يسبب التثبيت

استخدم هذه العلامة بحكمة أثناء جلسات تصحيح الأخطاء فقط، لأنها تؤدي إلى زيادة عبء الأداء.

  1. قم بتجميع الكود التجريبي الخاص بنا:

    javac Main.java
    
  2. ابدأ الكود المترجم باستخدام العلامة -Djdk.tracePinnedThreads=full:

    java -Djdk.tracePinnedThreads=full Main
    
  3. لاحظ الإخراج في وحدة التحكم، والذي يعرض معلومات مفصلة حول تثبيت الخيط الافتراضي:

    Thread[#29,ForkJoinPool-1-worker-1,5,CarrierThreads]
    java.base/java.lang.VirtualThread$VThreadContinuation.onPinned(VirtualThread.java:183)
    java.base/jdk.internal.vm.Continuation.onPinned0(Continuation.java:393)
    java.base/java.lang.VirtualThread.parkNanos(VirtualThread.java:621)
    java.base/java.lang.VirtualThread.sleepNanos(VirtualThread.java:791)
    java.base/java.lang.Thread.sleep(Thread.java:507)
    Counter.increment(Main.java:38) 
    
    

إصلاح التثبيت باستخدام أقفال إعادة الدخول

التثبيت هو سيناريو غير مرغوب فيه والذي يعيق أداء مؤشرات الترابط الافتراضية. تعمل أقفال إعادة الدخول كأداة فعالة لمواجهة التثبيت. إليك كيفية استخدام أقفال Reentrant للتخفيف من حالات التثبيت:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

public class Main {

  public static void main(String[] args) {

    Counter counter = new Counter();

    Runnable task = () -> {
      for (int i = 0; i 



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

ختاماً

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

بيان الافراج يتم استنساخ هذه المقالة على: https://dev.to/yanev/exploring-pinning-in-jvms-virtual-thread-mechanism-5h13؟1 إذا كان هناك أي انتهاك ، فيرجى الاتصال بـ [email protected] لحذفها.
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3