मल्टीथ्रेडिंग Java


किसी भी एप्लिकेशन में कई प्रक्रियाएँ (इंस्टेंस) हो सकती हैं। इनमें से प्रत्येक प्रक्रिया को या तो एकल थ्रेड या कई थ्रेड के रूप में असाइन किया जा सकता है। हम इस ट्यूटोरियल में देखेंगे कि एक ही समय में कई कार्य कैसे किए जाते हैं और थ्रेड्स और थ्रेड्स के बीच सिंक्रोनाइज़ेशन के बारे में भी अधिक जानेंगे।

सिंगल थ्रेड क्या है?

एक एकल धागा Java मूलतः यह हल्की तथा प्रसंस्करण की सबसे छोटी इकाई है। Java “थ्रेड क्लास” का उपयोग करके थ्रेड्स का उपयोग करता है। थ्रेड दो प्रकार के होते हैं – उपयोगकर्ता थ्रेड और डेमॉन थ्रेड (डेमन थ्रेड का उपयोग तब किया जाता है जब हम एप्लीकेशन को साफ करना चाहते हैं और बैकग्राउंड में इसका उपयोग किया जाता है)। जब कोई एप्लीकेशन सबसे पहले शुरू होती है, तो यूजर थ्रेड बनाया जाता है। उसके बाद, हम कई यूजर थ्रेड और डेमन थ्रेड बना सकते हैं।

एकल थ्रेड उदाहरण:

package demotest;

public class GuruThread
{
       public static void main(String[] args) {
              System.out.println("Single Thread");
       }
}

एकल धागे के लाभ:

  • सिस्टम में एकल थ्रेड के निष्पादन के कारण अनुप्रयोग में ओवरहेड कम हो जाता है
  • इसके अलावा, यह एप्लिकेशन की रखरखाव लागत को भी कम करता है।

मल्टीथ्रेडिंग क्या है? Java?

multithreading in Java CPU के अधिकतम उपयोग के लिए दो या अधिक थ्रेड्स को एक साथ निष्पादित करने की प्रक्रिया है। मल्टीथ्रेडेड एप्लिकेशन दो या अधिक थ्रेड्स को एक साथ निष्पादित करते हैं। इसलिए, इसे समवर्ती के रूप में भी जाना जाता है Java. प्रत्येक थ्रेड एक दूसरे के समानांतर चलता है। कई थ्रेड अलग-अलग मेमोरी क्षेत्र आवंटित नहीं करते हैं, इसलिए वे मेमोरी बचाते हैं। साथ ही, थ्रेड के बीच संदर्भ स्विचिंग में कम समय लगता है।

मल्टी थ्रेड का उदाहरण:

package demotest;
public class GuruThread1 implements Runnable
{
       public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

मल्टीथ्रेड के लाभ:

  • उपयोगकर्ता अवरुद्ध नहीं होते क्योंकि थ्रेड स्वतंत्र होते हैं, और हम एक समय में कई ऑपरेशन कर सकते हैं
  • चूंकि थ्रेड स्वतंत्र होते हैं, इसलिए यदि एक थ्रेड अपवाद का सामना करता है तो अन्य थ्रेड प्रभावित नहीं होंगे।

धागा जीवन चक्र Java

एक धागे का जीवनचक्र:

धागा जीवन चक्र Java
धागा जीवन चक्र Java

धागे के जीवन चक्र के विभिन्न चरण होते हैं जैसा कि ऊपर चित्र में दिखाया गया है:

  1. नया
  2. runnable
  3. रनिंग
  4. इंतज़ार कर रही
  5. मृत
  1. नई: इस चरण में, थ्रेड को क्लास “थ्रेड क्लास” का उपयोग करके बनाया जाता है। यह प्रोग्राम तक इस स्थिति में रहता है शुरू होता है धागा। इसे बोर्न थ्रेड के नाम से भी जाना जाता है।
  2. चलने योग्य: इस पृष्ठ में, थ्रेड का उदाहरण एक स्टार्ट विधि के साथ लागू किया जाता है। निष्पादन को समाप्त करने के लिए थ्रेड नियंत्रण शेड्यूलर को दिया जाता है। यह शेड्यूलर पर निर्भर करता है कि थ्रेड को चलाना है या नहीं।
  3. चल रहा है: जब थ्रेड निष्पादित करना शुरू करता है, तो स्थिति को “रनिंग” स्थिति में बदल दिया जाता है। शेड्यूलर थ्रेड पूल से एक थ्रेड का चयन करता है, और यह एप्लिकेशन में निष्पादित करना शुरू कर देता है।
  4. इंतज़ार कर रही: यह वह स्थिति है जब थ्रेड को प्रतीक्षा करनी पड़ती है। चूंकि एप्लिकेशन में कई थ्रेड चल रहे होते हैं, इसलिए थ्रेड के बीच सिंक्रोनाइज़ेशन की आवश्यकता होती है। इसलिए, एक थ्रेड को तब तक प्रतीक्षा करनी पड़ती है, जब तक कि दूसरा थ्रेड निष्पादित न हो जाए। इसलिए, इस स्थिति को प्रतीक्षा अवस्था कहा जाता है।
  5. मृत: यह वह स्थिति है जब थ्रेड समाप्त हो जाता है। थ्रेड चालू अवस्था में होता है और जैसे ही यह प्रोसेसिंग पूरी करता है, यह "मृत अवस्था" में चला जाता है।


मल्टीथ्रेडिंग के तरीके Java

थ्रेड्स के लिए आमतौर पर उपयोग की जाने वाली कुछ विधियाँ हैं:

विधि विवरण
शुरू() यह विधि थ्रेड का निष्पादन प्रारंभ करती है और JVM थ्रेड पर run() विधि को कॉल करता है.
नींद(int मिलीसेकंड) यह विधि थ्रेड को सुला देती है, इसलिए थ्रेड का निष्पादन कुछ मिलीसेकंड के लिए रुक जाता है और उसके बाद, थ्रेड फिर से निष्पादन शुरू कर देता है। यह थ्रेड्स के सिंक्रोनाइज़ेशन में मदद करता है।
getName () यह थ्रेड का नाम लौटाता है.
सेटप्राथमिकता(int नईप्राथमिकता) यह थ्रेड की प्राथमिकता बदल देता है.
उपज () इसके कारण वर्तमान थ्रेड रुक जाता है तथा अन्य थ्रेड निष्पादित होने लगते हैं।

उदाहरण: इस मल्टीथ्रेडिंग प्रोग्राम में Java उदाहरण के लिए, हम एक थ्रेड बनाने जा रहे हैं और थ्रेड के लिए उपलब्ध अंतर्निहित विधियों का पता लगाने जा रहे हैं।

package demotest;
public class thread_example1 implements Runnable {
    @Override
    public void run() {
    }
    public static void main(String[] args) {
        Thread guruthread1 = new Thread();
        guruthread1.start();
        try {
            guruthread1.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        guruthread1.setPriority(1);
        int gurupriority = guruthread1.getPriority();
        System.out.println(gurupriority);
        System.out.println("Thread Running");
  }
}

कोड का स्पष्टीकरण:

  • कोड लाइन 2: हम एक क्लास “thread_Example1” बना रहे हैं जो Runnable इंटरफ़ेस को कार्यान्वित कर रहा है (इसे किसी भी क्लास द्वारा कार्यान्वित किया जाना चाहिए जिसके इंस्टैंस को थ्रेड द्वारा निष्पादित किया जाना है।)
  • कोड लाइन 4: यह रन करने योग्य इंटरफ़ेस की रन विधि को ओवरराइड करता है क्योंकि उस विधि को ओवरराइड करना अनिवार्य है
  • कोड लाइन 6: यहां हमने मुख्य विधि को परिभाषित किया है जिसमें हम थ्रेड का निष्पादन शुरू करेंगे।
  • कोड लाइन 7: यहां हम थ्रेड की एक नई क्लास को इन्स्टैंसिएट करके “guruthread1” नाम से एक नया थ्रेड बना रहे हैं।
  • कोड लाइन 8: हम "guruthread1" इंस्टेंस का उपयोग करके थ्रेड की "start" विधि का उपयोग करेंगे। यहाँ थ्रेड निष्पादित होना शुरू हो जाएगा।
  • कोड लाइन 10: यहाँ हम “guruthread1” इंस्टेंस का उपयोग करके थ्रेड की “sleep” विधि का उपयोग कर रहे हैं। इसलिए, थ्रेड 1000 मिलीसेकंड के लिए सो जाएगा।
  • कोड 9-14: यहां हमने स्लीप विधि को ट्राई कैच ब्लॉक में रखा है क्योंकि यहां चेक अपवाद होता है, अर्थात इंटरप्टेड अपवाद।
  • कोड लाइन 15: यहां हम थ्रेड की प्राथमिकता को 1 पर सेट कर रहे हैं, चाहे वह किसी भी प्राथमिकता पर हो
  • कोड लाइन 16: यहाँ हम getPriority() का उपयोग करके थ्रेड की प्राथमिकता प्राप्त कर रहे हैं
  • कोड लाइन 17: यहाँ हम getPriority से प्राप्त मान को प्रिंट कर रहे हैं
  • कोड लाइन 18: यहां हम एक पाठ लिख रहे हैं जो धागा चल रहा है।

जब आप उपरोक्त कोड निष्पादित करते हैं, तो आपको निम्नलिखित आउटपुट मिलता है:

थ्रेड उदाहरण Java

आउटपुट:

5 थ्रेड प्राथमिकता है, और थ्रेड रनिंग वह पाठ है जो हमारे कोड का आउटपुट है।

Java धागा Syncतुल्यकालन

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

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

इसे निम्नलिखित रूप में लिखा जा सकता है:

Synchronized(object)
{  
        //Block of statements to be synchronized
}

मल्टीथ्रेडिंग Java उदाहरण कार्यक्रम

इस मल्टीथ्रेडिंग में Java उदाहरण के लिए, हम दो थ्रेड लेंगे और थ्रेड के नाम प्राप्त करेंगे।

Example1:

GuruThread1.java
package demotest;
public class GuruThread1 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

कोड का स्पष्टीकरण:

  • कोड लाइन 3: हमने एक क्लास “GuruThread1” लिया है जो Runnable को कार्यान्वित करता है (इसे किसी भी क्लास द्वारा कार्यान्वित किया जाना चाहिए जिसके इंस्टैंस को थ्रेड द्वारा निष्पादित किया जाना है।)
  • कोड लाइन 8: यह क्लास की मुख्य विधि है
  • कोड लाइन 9: यहां हम थ्रेड क्लास को इंस्टैंशिएट कर रहे हैं और "guruThread1" नाम से एक इंस्टैंस बना रहे हैं और एक थ्रेड बना रहे हैं।
  • कोड लाइन 10: यहां हम थ्रेड क्लास को इंस्टैंशिएट कर रहे हैं और "guruThread2" नामक एक इंस्टैंस बना रहे हैं और एक थ्रेड बना रहे हैं।
  • कोड लाइन 11: हम धागा यानि गुरु थ्रेड 1 शुरू कर रहे हैं।
  • कोड लाइन 12: हम धागा यानि गुरु थ्रेड 2 शुरू कर रहे हैं।
  • कोड लाइन 13: “थ्रेड नाम निम्नलिखित हैं:” के रूप में पाठ आउटपुट करना
  • कोड लाइन 14: थ्रेड क्लास की getName() विधि का उपयोग करके थ्रेड 1 का नाम प्राप्त करना।
  • कोड लाइन 15: थ्रेड क्लास की getName() विधि का उपयोग करके थ्रेड 2 का नाम प्राप्त करना।

जब आप उपरोक्त कोड निष्पादित करते हैं, तो आपको निम्नलिखित आउटपुट मिलता है:

Java मल्टीथ्रेडिंग उदाहरण

आउटपुट:

थ्रेड नाम यहाँ इस प्रकार आउटपुट किए जा रहे हैं

  • Guru1
  • Guru2

उदाहरण 2:

इस मल्टीथ्रेडिंग में Java उदाहरण के लिए, हम एक रन करने योग्य इंटरफ़ेस के run() और start() विधियों को ओवरराइड करने के बारे में सीखेंगे और उस क्लास के दो थ्रेड बनाएंगे और उन्हें तदनुसार चलाएंगे।

इसके अलावा, हम दो कक्षाएं ले रहे हैं,

  • एक जो रननेबल इंटरफ़ेस को लागू करेगा और
  • दूसरा, जिसमें मुख्य विधि होगी और तदनुसार निष्पादित होगी।
package demotest;
public class GuruThread2 {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GuruThread3 threadguru1 = new GuruThread3("guru1");
  threadguru1.start();
  GuruThread3 threadguru2 = new GuruThread3("guru2");
  threadguru2.start();
 }
}
class GuruThread3 implements Runnable {
 Thread guruthread;
 private String guruname;
 GuruThread3(String name) {
  guruname = name;
 }
 @Override
 public void run() {
  System.out.println("Thread running" + guruname);
  for (int i = 0; i < 4; i++) {
   System.out.println(i);
   System.out.println(guruname);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    System.out.println("Thread has been interrupted");
   }
  }
 }
 public void start() {
  System.out.println("Thread started");
  if (guruthread == null) {
   guruthread = new Thread(this, guruname);
   guruthread.start();
  }
 }
}

कोड का स्पष्टीकरण:

  • कोड लाइन 2: यहां हम एक क्लास “GuruThread2” ले रहे हैं जिसमें मुख्य विधि होगी।
  • कोड लाइन 4: यहां हम क्लास की मुख्य विधि ले रहे हैं।
  • कोड लाइन 6-7: यहां हम क्लास गुरुथ्रेड3 (जो कोड की नीचे की पंक्तियों में बनाया गया है) का एक उदाहरण "थ्रेडगुरु1" के रूप में बना रहे हैं और हम थ्रेड शुरू कर रहे हैं।
  • कोड लाइन 8-9: यहां हम क्लास गुरुथ्रेड3 (जो कोड की नीचे की पंक्तियों में बनाया गया है) का एक और उदाहरण "थ्रेडगुरु2" के रूप में बना रहे हैं और हम थ्रेड शुरू कर रहे हैं।
  • कोड लाइन 11: यहां हम एक क्लास “GuruThread3” बना रहे हैं जो रननेबल इंटरफ़ेस को कार्यान्वित कर रहा है (इसे किसी भी क्लास द्वारा कार्यान्वित किया जाना चाहिए जिसके इंस्टैंस को थ्रेड द्वारा निष्पादित किया जाना है।)
  • कोड लाइन 13-14: हम दो वर्ग चर ले रहे हैं जिनमें से एक थ्रेड वर्ग का है और दूसरा स्ट्रिंग वर्ग का है।
  • कोड लाइन 15-18: हम गुरुथ्रेड3 कन्स्ट्रक्टर को ओवरराइड कर रहे हैं, जो एक तर्क को स्ट्रिंग प्रकार के रूप में लेता है (जो थ्रेड का नाम है) जिसे क्लास वेरिएबल गुरुनाम को सौंपा जाता है और इस प्रकार थ्रेड का नाम संग्रहीत किया जाता है।
  • कोड लाइन 20: यहां हम runnable इंटरफ़ेस की run() विधि को ओवरराइड कर रहे हैं।
  • कोड लाइन 21: हम println स्टेटमेंट का उपयोग करके थ्रेड नाम आउटपुट कर रहे हैं।
  • कोड लाइन 22-31: यहाँ हम काउंटर को 0 से आरंभीकृत करके फॉर लूप का उपयोग कर रहे हैं, और यह 4 से कम नहीं होना चाहिए (हम कोई भी संख्या ले सकते हैं इसलिए यहाँ लूप 4 बार चलेगा) और काउंटर को बढ़ा रहे हैं। हम थ्रेड का नाम प्रिंट कर रहे हैं और थ्रेड को ट्राई-कैच ब्लॉक के भीतर 1000 मिलीसेकंड के लिए स्लीप भी कर रहे हैं क्योंकि स्लीप विधि ने चेक अपवाद उठाया है।
  • कोड लाइन 33: यहां हम रननेबल इंटरफ़ेस की स्टार्ट विधि को ओवरराइड कर रहे हैं।
  • कोड लाइन 35: हम “थ्रेड शुरू हुआ” पाठ आउटपुट कर रहे हैं।
  • कोड लाइन 36-40: यहाँ हम यह जाँचने के लिए if कंडीशन ले रहे हैं कि क्लास वेरिएबल guruthread में मान है या नहीं। अगर यह शून्य है तो हम थ्रेड क्लास का उपयोग करके एक इंस्टेंस बना रहे हैं जो नाम को पैरामीटर के रूप में लेता है (जिसके लिए कंस्ट्रक्टर में मान निर्दिष्ट किया गया था)। जिसके बाद थ्रेड को start() विधि का उपयोग करके शुरू किया जाता है।

जब आप उपरोक्त कोड निष्पादित करते हैं तो आपको निम्नलिखित आउटपुट मिलता है:

मल्टीथ्रेडिंग उदाहरण Java

उत्पादन:

दो थ्रेड हैं, इसलिए हमें दो बार संदेश मिलता है “थ्रेड शुरू हुआ”।

हमें थ्रेड के नाम वैसे ही मिलते हैं जैसे हमने उन्हें आउटपुट किया है।

यह फॉर लूप में चला जाता है जहां हम काउंटर और थ्रेड नाम प्रिंट कर रहे हैं और काउंटर 0 से शुरू होता है।

लूप तीन बार निष्पादित होता है और बीच में थ्रेड 1000 मिलीसेकंड के लिए सो जाता है।

अतः, पहले हमें गुरु1, फिर गुरु2 और फिर गुरु2 मिलता है, क्योंकि थ्रेड यहां 1000 मिलीसेकंड के लिए सोता है और फिर गुरु1 और फिर गुरु1, थ्रेड 1000 मिलीसेकंड के लिए सोता है, इसलिए हमें गुरु2 और फिर गुरु1 मिलता है।

सारांश

इस ट्यूटोरियल में, हमने मल्टीथ्रेडेड अनुप्रयोगों को देखा Java और एकल और बहु ​​थ्रेड का उपयोग कैसे करें Java.

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