हम इस ट्यूटोरियल में सीखने वाले है कि जावा मल्टीथ्रीडिंग (Java Multithreading in Hindi) और हम इसे कैसे इस्तमाल कर सकते हैं? जावा एक multi-threaded प्रोग्रामिंग भाषा है जिसका अर्थ है कि हम जावा का उपयोग करके multi-threaded प्रोग्राम विकसित कर सकते हैं। एक multi-threaded प्रोग्राम में दो या दो से अधिक भाग होते हैं जो concurrently रूप से चल सकते हैं और प्रत्येक भाग एक ही समय में उपलब्ध संसाधनों का optimal उपयोग करते हुए एक अलग कार्य को संभाल सकता है, खासकर जब आपके कंप्यूटर में कई सीपीयू हों।
परिभाषा के अनुसार, मल्टीटास्किंग तब होता है जब कई प्रक्रियाएँ सीपीयू जैसे सामान्य प्रसंस्करण संसाधनों को साझा करती हैं। मल्टी-थ्रेडिंग मल्टीटास्किंग के विचार को उन अनुप्रयोगों में विस्तारित करता है जहां आप एक ही एप्लिकेशन के भीतर विशिष्ट संचालन को अलग-अलग थ्रेड्स में उप-विभाजित कर सकते हैं। प्रत्येक थ्रेड समानांतर में चल सकता है। ओएस प्रसंस्करण समय को न केवल विभिन्न अनुप्रयोगों के बीच विभाजित करता है, बल्कि एक आवेदन के भीतर प्रत्येक थ्रेड के बीच भी विभाजित करता है।
Table of Contents
मल्टी-थ्रेडिंग आपको एक तरह से लिखने में सक्षम बनाता है जहां एक ही प्रोग्राम में कई गतिविधियां concurrently रूप से आगे बढ़ सकती हैं।
Life Cycle of a Thread in Hindi
एक धागा अपने जीवन चक्र में विभिन्न चरणों से गुजरता है। उदाहरण के लिए, एक धागा पैदा होता है, शुरू होता है, चलता है और फिर मर जाता है। निम्नलिखित आरेख एक धागे के पूर्ण जीवन चक्र को दर्शाता है।
जीवन चक्र के निम्नलिखित चरण हैं –
New − नया थ्रेड नई अवस्था में अपना जीवन चक्र शुरू करता है। यह इस अवस्था में तब तक रहता है जब तक कि प्रोग्राम थ्रेड शुरू नहीं कर देता। इसे जन्म सूत्र भी कहा जाता है।
रननेबल (Runnable) − नए थ्रेड के शुरू होने के बाद, थ्रेड रन करने योग्य हो जाता है। इस अवस्था में एक थ्रेड को अपना कार्य Execution करने वाला माना जाता है।
वेटिंग (Waiting) − कभी-कभी, एक थ्रेड वेटिंग स्थिति में चला जाता है जबकि थ्रेड किसी कार्य को करने के लिए दूसरे थ्रेड की प्रतीक्षा करता है। एक थ्रेड रन करने योग्य स्थिति में वापस तभी आता है जब कोई अन्य थ्रेड वेटिंग थ्रेड को Execution करना जारी रखने का संकेत देता है।
समयबद्ध प्रतीक्षा (Timed Waiting) – एक चलने योग्य धागा समय के Specified अंतराल के लिए समयबद्ध प्रतीक्षा स्थिति में प्रवेश कर सकता है। इस स्थिति में एक थ्रेड रन करने योग्य स्थिति में वापस आ जाता है जब उस समय अंतराल की समय सीमा समाप्त हो जाती है या जब वह घटना होती है जिसकी वह प्रतीक्षा कर रहा होता है।
टर्मिनेटेड (डेड) (Terminated (Dead)) – एक रननेबल थ्रेड टर्मिनेटेड स्थिति में प्रवेश करता है जब यह अपना कार्य पूरा करता है या अन्यथा समाप्त हो जाता है।
थ्रेड प्राथमिकताएं (Thread Priorities in Hindi)
प्रत्येक जावा थ्रेड की एक प्राथमिकता होती है जो ऑपरेटिंग सिस्टम को उस क्रम को निर्धारित करने में मदद करती है जिसमें थ्रेड शेड्यूल किए जाते हैं।
जावा थ्रेड प्राथमिकताएं MIN_PRIORITY (1 की स्थिरांक) और MAX_PRIORITY (10 की स्थिरांक) के बीच की सीमा में हैं। डिफ़ॉल्ट रूप से, प्रत्येक थ्रेड को NORM_PRIORITY (5 का स्थिर) प्राथमिकता दी जाती है।
उच्च प्राथमिकता वाले थ्रेड्स एक प्रोग्राम के लिए अधिक महत्वपूर्ण होते हैं और निम्न-प्राथमिकता वाले थ्रेड्स से पहले प्रोसेसर समय आवंटित किया जाना चाहिए। हालाँकि, थ्रेड प्राथमिकताएँ उस क्रम की गारंटी नहीं दे सकती हैं जिसमें थ्रेड्स Execution होते हैं और बहुत अधिक प्लेटफ़ॉर्म पर निर्भर होते हैं।
एक रननेबल इंटरफ़ेस लागू करके एक थ्रेड बनाएँ (Create a Thread by Implementing a Runnable Interface)
यदि आपकी कक्षा को थ्रेड के रूप में Execution करने का इरादा है तो आप इसे रननेबल इंटरफ़ेस लागू करके प्राप्त कर सकते हैं। आपको तीन बुनियादी चरणों का पालन करना होगा –
स्टेप 1
पहले चरण के रूप में, आपको रननेबल इंटरफ़ेस द्वारा प्रदान की गई run() विधि को लागू करने की आवश्यकता है। यह विधि थ्रेड के लिए एक प्रवेश बिंदु प्रदान करती है और आप अपना पूरा व्यावसायिक तर्क इस विधि के अंदर रखेंगे। निम्नलिखित run() विधि का एक सरल सिंटैक्स है –
public void run( )
स्टेप 2
दूसरे चरण के रूप में आप निम्न कन्स्ट्रक्टर का उपयोग करके थ्रेड ऑब्जेक्ट को तुरंत चालू करेंगे –
दूसरे चरण के रूप में आप निम्न कन्स्ट्रक्टर का उपयोग करके थ्रेड ऑब्जेक्ट को तुरंत चालू करेंगे –
Thread(Runnable threadObj, String threadName);
जहां, threadObj एक वर्ग का एक उदाहरण है जो रननेबल इंटरफ़ेस को लागू करता है और थ्रेडनाम नए थ्रेड को दिया गया नाम है।
स्टेप 3
एक बार थ्रेड ऑब्जेक्ट बन जाने के बाद, आप इसे start() विधि को कॉल करके शुरू कर सकते हैं, जो कॉल टू run( ) विधि को Execution करता है। निम्नलिखित start() विधि का एक सरल सिंटैक्स है –
void start();
उदाहरण
यहाँ एक उदाहरण है जो एक नया थ्रेड बनाता है और उसे चलाना शुरू करता है –
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name) {
threadName = name;
System.out.println(“Creating ” + threadName );
}
public void run() {
System.out.println(“Running ” + threadName );
try {
for(int i = 4; i > 0; i–) {
System.out.println(“Thread: ” + threadName + “, ” + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println(“Thread ” + threadName + ” interrupted.”);
}
System.out.println(“Thread ” + threadName + ” exiting.”);
}
public void start () {
System.out.println(“Starting ” + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( “Thread-1”);
R1.start();
RunnableDemo R2 = new RunnableDemo( “Thread-2”);
R2.start();
}
}
यह निम्नलिखित परिणाम देगा –
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
थ्रेड क्लास को एक्सटेंड करके थ्रेड बनाएं (Create a Thread by Extending a Thread Class)
थ्रेड बनाने का दूसरा तरीका एक नया वर्ग बनाना है जो निम्नलिखित दो सरल चरणों का उपयोग करके थ्रेड क्लास का विस्तार करता है। यह दृष्टिकोण थ्रेड क्लास में उपलब्ध विधियों का उपयोग करके बनाए गए कई थ्रेड्स को संभालने में अधिक लचीलापन प्रदान करता है।
स्टेप 1
आपको थ्रेड क्लास में उपलब्ध run() विधि को ओवरराइड करना होगा। यह विधि थ्रेड के लिए एक प्रवेश बिंदु प्रदान करती है और आप अपना पूरा व्यावसायिक तर्क इस विधि के अंदर रखेंगे। निम्नलिखित run() विधि का एक सरल सिंटैक्स है –
public void run( )
चरण दो
एक बार थ्रेड ऑब्जेक्ट बन जाने के बाद, आप इसे स्टार्ट () विधि को कॉल करके शुरू कर सकते हैं, जो कॉल टू run() विधि को Execution करता है। निम्नलिखित स्टार्ट () विधि का एक सरल सिंटैक्स है –
void start( );
उदाहरण
यहां थ्रेड को बढ़ाने के लिए पिछले प्रोग्राम को फिर से लिखा गया है –
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println(“Creating ” + threadName );
}
public void run() {
System.out.println(“Running ” + threadName );
try {
for(int i = 4; i > 0; i–) {
System.out.println(“Thread: ” + threadName + “, ” + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println(“Thread ” + threadName + ” interrupted.”);
}
System.out.println(“Thread ” + threadName + ” exiting.”);
}
public void start () {
System.out.println(“Starting ” + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo( “Thread-1”);
T1.start();
ThreadDemo T2 = new ThreadDemo( “Thread-2”);
T2.start();
}
}
यह निम्नलिखित परिणाम देगा –
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
थ्रेड तरीके (Thread Methods in Hindi)
थ्रेड क्लास में उपलब्ध महत्वपूर्ण विधियों की सूची निम्नलिखित है।
Sr.No. | Method & Description |
1 | public void start() थ्रेड को Execution के एक अलग पथ में प्रारंभ करता है, फिर इस थ्रेड ऑब्जेक्ट पर run() विधि को लागू करता है। |
2 | public void run() यदि यह थ्रेड ऑब्जेक्ट एक अलग रननेबल लक्ष्य का उपयोग करके Immediately किया गया था, तो उस रननेबल ऑब्जेक्ट पर run() विधि लागू की जाती है। |
3 | public final void setName(String name) थ्रेड ऑब्जेक्ट का नाम बदलें। नाम प्राप्त करने के लिए एक getName() विधि भी है। |
4 | public final void setPriority(int priority) इस थ्रेड ऑब्जेक्ट की प्राथमिकता सेट करें। संभावित मान 1 और 10 के बीच हैं। |
5 | public final void setDaemon(boolean on) सत्य का एक पैरामीटर इस थ्रेड को डेमन थ्रेड के रूप में दर्शाता है। |
6 | public final void join(long millisec) वर्तमान थ्रेड इस विधि को दूसरे थ्रेड पर आमंत्रित करता है, जिससे वर्तमान थ्रेड ब्लॉक हो जाता है जब तक कि दूसरा थ्रेड समाप्त नहीं हो जाता या मिलीसेकंड की Specified संख्या पास नहीं हो जाती। |
7 | public void interrupt() इस थ्रेड को बाधित करता है, जिससे यह किसी भी कारण से blocked होने पर Execution जारी रखता है। |
8 | public final boolean isAlive() यदि धागा जीवित है, तो यह सच हो जाता है, जो कि धागा शुरू होने के बाद किसी भी समय होता है लेकिन पूरा होने से पहले चलता है। |
पिछली विधियों को किसी विशेष थ्रेड ऑब्जेक्ट पर लागू किया जाता है। थ्रेड क्लास में निम्नलिखित विधियाँ स्थिर हैं। स्थैतिक विधियों में से एक को लागू करने से वर्तमान में चल रहे थ्रेड पर ऑपरेशन होता है।
Sr.No. | Method & Description |
1 | public static void yield() वर्तमान में चल रहे थ्रेड को उसी प्राथमिकता के किसी भी अन्य थ्रेड को yield करने का कारण बनता है जो शेड्यूल होने की प्रतीक्षा कर रहा है। |
2 | public static void sleep(long millisec) कम से कम मिलीसेकंड की Specified संख्या के लिए वर्तमान में चल रहे थ्रेड को ब्लॉक करने का कारण बनता है। |
3 | public static boolean holdsLock(Object x) यदि वर्तमान थ्रेड दिए गए ऑब्जेक्ट पर लॉक रखता है तो सत्य वापस आ जाता है। |
4 | public static Thread currentThread() वर्तमान में चल रहे थ्रेड का संदर्भ देता है, जो कि वह थ्रेड है जो इस विधि को कॉल करता है। |
5 | public static void dumpStack() वर्तमान में चल रहे थ्रेड के लिए स्टैक ट्रेस प्रिंट करता है, जो मल्टीथ्रेडेड एप्लिकेशन को डीबग करते समय उपयोगी होता है। |
उदाहरण
निम्न थ्रेडक्लासडेमो प्रोग्राम थ्रेड क्लास के इन तरीकों में से कुछ को प्रदर्शित करता है। एक वर्ग DisplayMessage पर विचार करें जो रननेबल – को लागू करता है
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
public class DisplayMessage implements Runnable {
private String message;
public DisplayMessage(String message) {
this.message = message;
}
public void run() {
while(true) {
System.out.println(message);
}
}
}
निम्नलिखित एक अन्य वर्ग है जो थ्रेड वर्ग का विस्तार करता है –
// File Name : GuessANumber.java
// Create a thread to extentd Thread
public class GuessANumber extends Thread {
private int number;
public GuessANumber(int number) {
this.number = number;
}
public void run() {
int counter = 0;
int guess = 0;
do {
guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName() + ” guesses ” + guess);
counter++;
} while(guess != number);
System.out.println(“** Correct!” + this.getName() + “in” + counter + “guesses.**”);
}
}
निम्नलिखित मुख्य कार्यक्रम है, जो उपरोक्त परिभाषित वर्गों का उपयोग करता है –
// File Name : ThreadClassDemo.java
public class ThreadClassDemo {
public static void main(String [] args) {
Runnable hello = new DisplayMessage(“Hello”);
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName(“hello”);
System.out.println(“Starting hello thread…”);
thread1.start();
Runnable bye = new DisplayMessage(“Goodbye”);
Thread thread2 = new Thread(bye);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println(“Starting goodbye thread…”);
thread2.start();
System.out.println(“Starting thread3…”);
Thread thread3 = new GuessANumber(27);
thread3.start();
try {
thread3.join();
} catch (InterruptedException e) {
System.out.println(“Thread interrupted.”);
}
System.out.println(“Starting thread4…”);
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println(“main() is ending…”);
}
}
यह निम्नलिखित परिणाम उत्पन्न करेगा। आप इस उदाहरण को बार-बार आजमा सकते हैं और आपको हर बार अलग परिणाम मिलेगा।
Output
Starting hello thread…
Starting goodbye thread…
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
…….
हम उम्मीद करते है कि आपको “जावा मल्टीथ्रीडिंग (Java Multithreading in Hindi)” से सम्बंधित जानकारी हिंदी में समझ में आयी होंगी यदि आपको बताई गई जानकारी अच्छी लगी हो तो अपने दोस्तों में ऐसे शेयर करे जिससे उनकी भी हेल्प हो सके धन्यवाद!