"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > जेवीएम के वर्चुअल थ्रेड मैकेनिज्म में पिनिंग की खोज

जेवीएम के वर्चुअल थ्रेड मैकेनिज्म में पिनिंग की खोज

2024-11-08 को प्रकाशित
ब्राउज़ करें:317

जावा के वर्चुअल थ्रेड पारंपरिक ओएस थ्रेड के लिए एक हल्का विकल्प प्रदान करते हैं, जो कुशल समवर्ती प्रबंधन को सक्षम बनाता है। लेकिन सर्वोत्तम प्रदर्शन के लिए उनके व्यवहार को समझना महत्वपूर्ण है। यह ब्लॉग पोस्ट पिनिंग के बारे में विस्तार से बताता है, एक ऐसा परिदृश्य जो वर्चुअल थ्रेड निष्पादन को प्रभावित कर सकता है, और इसकी निगरानी और समाधान करने के लिए तकनीकों की खोज करता है।

वर्चुअल थ्रेड्स: एक हल्का समवर्ती दृष्टिकोण

जावा के वर्चुअल थ्रेड्स प्रबंधित इकाइयाँ हैं जो अंतर्निहित ऑपरेटिंग सिस्टम थ्रेड्स (कैरियर थ्रेड्स) के शीर्ष पर चलती हैं। वे कई ओएस थ्रेड बनाने की तुलना में समवर्तीता को संभालने का अधिक कुशल तरीका प्रदान करते हैं, क्योंकि वे कम ओवरहेड खर्च करते हैं। JVM वर्चुअल थ्रेड को वाहक थ्रेड में गतिशील रूप से मैप करता है, जिससे बेहतर संसाधन उपयोग की अनुमति मिलती है।

  • जेवीएम द्वारा प्रबंधित: ऑपरेटिंग सिस्टम द्वारा सीधे प्रबंधित किए जाने वाले ओएस थ्रेड्स के विपरीत, वर्चुअल थ्रेड्स जावा वर्चुअल मशीन (जेवीएम) द्वारा बनाए और शेड्यूल किए जाते हैं। यह जेवीएम वातावरण के भीतर बेहतर नियंत्रण और अनुकूलन की अनुमति देता है।

  • कम ओवरहेड: वर्चुअल थ्रेड बनाने और प्रबंधित करने में ओएस थ्रेड की तुलना में काफी कम ओवरहेड खर्च होता है। ऐसा इसलिए है क्योंकि JVM कम संख्या में अंतर्निहित OS थ्रेड का उपयोग करके वर्चुअल थ्रेड के एक बड़े पूल को कुशलतापूर्वक प्रबंधित कर सकता है।

  • मौजूदा कोड के साथ संगतता: वर्चुअल थ्रेड्स को मौजूदा जावा कोड के साथ सहजता से एकीकृत करने के लिए डिज़ाइन किया गया है। उनका उपयोग पारंपरिक ओएस थ्रेड्स के साथ किया जा सकता है और समवर्ती प्रबंधन के लिए एक्ज़ीक्यूटर और एक्ज़ीक्यूटरसर्विस जैसी परिचित संरचनाओं के भीतर काम किया जा सकता है।

नीचे दिया गया चित्र वर्चुअल थ्रेड और प्लेटफ़ॉर्म थ्रेड के बीच संबंध दिखाता है:

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 



इस उदाहरण में, जब एक वर्चुअल थ्रेड सिंक्रोनाइज़्ड ब्लॉक में प्रवेश करता है, तो यह उसके कैरियर थ्रेड पर पिन हो जाता है, लेकिन यह हमेशा सच नहीं होता है। जावा का सिंक्रोनाइज़्ड कीवर्ड अकेले वर्चुअल थ्रेड्स में थ्रेड पिनिंग के लिए पर्याप्त नहीं है। थ्रेड पिनिंग के लिए, सिंक्रोनाइज़्ड ब्लॉक के भीतर एक अवरोधक बिंदु होना चाहिए जो वर्चुअल थ्रेड को पार्क को ट्रिगर करने का कारण बनता है, और अंततः इसके वाहक थ्रेड से अनमाउंटिंग की अनुमति नहीं देता है। थ्रेड पिनिंग के कारण प्रदर्शन में कमी आ सकती है क्योंकि इससे हल्के/आभासी थ्रेड के उपयोग के लाभ समाप्त हो जाएंगे।

जब भी कोई वर्चुअल थ्रेड किसी अवरोध बिंदु का सामना करता है, तो उसकी स्थिति पार्किंग में परिवर्तित हो जाती है। इस स्थिति परिवर्तन को 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=पूर्ण ध्वज के साथ प्रारंभ करें:

    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) 
    
    

रीएंट्रेंट लॉक्स के साथ पिनिंग को ठीक करना

पिनिंग एक अवांछनीय परिदृश्य है जो वर्चुअल थ्रेड के प्रदर्शन को बाधित करता है। रीएंट्रेंट ताले पिनिंग का प्रतिकार करने के लिए एक प्रभावी उपकरण के रूप में काम करते हैं। यहां बताया गया है कि आप पिनिंग स्थितियों को कम करने के लिए रीएंट्रेंट लॉक का उपयोग कैसे कर सकते हैं:

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 



अद्यतन उदाहरण में, हम सिंक्रोनाइज़्ड ब्लॉक के बजाय रीएंट्रेंटलॉक का उपयोग करते हैं। थ्रेड लॉक प्राप्त कर सकता है और अपना ऑपरेशन पूरा होने के तुरंत बाद इसे जारी कर सकता है, जिससे सिंक्रोनाइज्ड ब्लॉक की तुलना में पिनिंग की अवधि संभावित रूप से कम हो सकती है, जो लॉक को लंबी अवधि तक रोक कर रख सकता है।

निष्कर्ष के तौर पर

जावा के आभासी धागे भाषा के विकास और क्षमताओं के प्रमाण के रूप में खड़े हैं। वे पारंपरिक ओएस थ्रेड्स के लिए एक नया, हल्का विकल्प प्रदान करते हैं, जो कुशल समवर्ती प्रबंधन के लिए एक पुल प्रदान करते हैं। गहराई तक जाने और थ्रेड पिनिंग जैसी प्रमुख अवधारणाओं को समझने में समय लगाने से डेवलपर्स को इन हल्के धागों की पूरी क्षमता का लाभ उठाने की जानकारी मिल सकती है। यह ज्ञान न केवल डेवलपर्स को आगामी सुविधाओं का लाभ उठाने के लिए तैयार करता है बल्कि उन्हें उनकी वर्तमान परियोजनाओं में जटिल समवर्ती नियंत्रण मुद्दों को अधिक प्रभावी ढंग से हल करने के लिए भी सशक्त बनाता है।

विज्ञप्ति वक्तव्य यह लेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/yanev/exploring-pinning-in-jvms-virtual-thread-mechanism-5h13?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3