CodeGym/Java Blog/अनियमित/जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उ...
John Squirrels
स्तर 41
San Francisco

जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर। भाग 2

अनियमित ग्रुप में प्रकाशित
सदस्य
जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर। भाग ---- पहलाजावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर।  भाग 2 - 1

बहु सूत्रण

24. मैं जावा में एक नया थ्रेड कैसे बना सकता हूँ?

एक तरह से या किसी अन्य, थ्रेड वर्ग का उपयोग करके एक धागा बनाया जाता है। लेकिन ऐसा करने के कई तरीके हैं…
  1. Java.lang.Thread इनहेरिट करें ।
  2. Java.lang.Runnable इंटरफ़ेस लागू करें - थ्रेड क्लास का कंस्ट्रक्टर एक रननेबल ऑब्जेक्ट लेता है।
आइए उनमें से प्रत्येक के बारे में बात करें।

थ्रेड क्लास इनहेरिट करें

इस मामले में, हम अपनी कक्षा को java.lang.Thread इनहेरिट करते हैं । इसमें एक रन () विधि है, और हमें बस यही चाहिए। नए सूत्र का सारा जीवन और तर्क इसी पद्धति में होगा। यह नए धागे के लिए एक मुख्य विधि की तरह है । उसके बाद, जो कुछ बचता है वह हमारी कक्षा का एक ऑब्जेक्ट बनाना है और स्टार्ट () विधि को कॉल करना है। यह एक नया सूत्र बनाएगा और इसके तर्क को क्रियान्वित करना शुरू करेगा। चलो एक नज़र मारें:
/**
* An example of how to create threads by inheriting the {@link Thread} class.
*/
class ThreadInheritance extends Thread {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance threadInheritance1 = new ThreadInheritance();
       ThreadInheritance threadInheritance2 = new ThreadInheritance();
       ThreadInheritance threadInheritance3 = new ThreadInheritance();
       threadInheritance1.start();
       threadInheritance2.start();
       threadInheritance3.start();
   }
}
कंसोल आउटपुट कुछ ऐसा होगा:
थ्रेड-1 थ्रेड-0 थ्रेड-2
यही है, यहां तक ​​​​कि हम देखते हैं कि धागे को क्रम में निष्पादित नहीं किया जाता है, बल्कि जेवीएम उन्हें चलाने के लिए उपयुक्त देखता है :)

रननेबल इंटरफ़ेस को लागू करें

यदि आप इनहेरिटेंस के खिलाफ हैं और/या पहले से ही किसी अन्य वर्ग को इनहेरिट करते हैं, तो आप java.lang.Runnable इंटरफ़ेस का उपयोग कर सकते हैं। यहां, हम अपनी कक्षा को रन () विधि को लागू करके इस इंटरफ़ेस को लागू करते हैं , जैसा कि ऊपर दिए गए उदाहरण में है। जो कुछ बचा है वह थ्रेड ऑब्जेक्ट बनाना है । ऐसा लगता है कि कोड की अधिक पंक्तियाँ बदतर हैं। लेकिन हम जानते हैं कि विरासत कितनी हानिकारक है और इससे हर तरह से बचना बेहतर है;) जरा गौर करें:
/**
* An example of how to create threads from the {@link Runnable} interface.
* It's easier than easy — we implement this interface and then pass an instance of our object
* to the constructor.
*/
class ThreadInheritance implements Runnable {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance runnable1 = new ThreadInheritance();
       ThreadInheritance runnable2 = new ThreadInheritance();
       ThreadInheritance runnable3 = new ThreadInheritance();

       Thread threadRunnable1 = new Thread(runnable1);
       Thread threadRunnable2 = new Thread(runnable2);
       Thread threadRunnable3 = new Thread(runnable3);

       threadRunnable1.start();
       threadRunnable2.start();
       threadRunnable3.start();
   }
}
और यहाँ परिणाम है:
थ्रेड-0 थ्रेड-1 थ्रेड-2

25. प्रोसेस और थ्रेड में क्या अंतर है?

जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर।  भाग 2 - 2एक प्रक्रिया और एक थ्रेड निम्नलिखित तरीकों से भिन्न होते हैं:
  1. एक रनिंग प्रोग्राम को एक प्रोसेस कहा जाता है, लेकिन एक थ्रेड एक प्रोसेस का एक टुकड़ा है।
  2. प्रक्रियाएं स्वतंत्र हैं, लेकिन धागे प्रक्रिया के टुकड़े हैं।
  3. प्रक्रियाओं में स्मृति में अलग-अलग पता स्थान होते हैं, लेकिन धागे एक सामान्य पता स्थान साझा करते हैं।
  4. प्रक्रियाओं के बीच स्विच करने की तुलना में थ्रेड्स के बीच संदर्भ स्विचिंग तेज़ है।
  5. इंटर-प्रोसेस कम्युनिकेशन इंटर-थ्रेड कम्युनिकेशन की तुलना में धीमा और अधिक महंगा है।
  6. पैरेंट प्रोसेस में कोई भी बदलाव चाइल्ड प्रोसेस को प्रभावित नहीं करता है, लेकिन पेरेंट थ्रेड में बदलाव चाइल्ड थ्रेड को प्रभावित कर सकता है।

26. मल्टीथ्रेडिंग के क्या फायदे हैं?

  1. मल्टीथ्रेडिंग एक एप्लिकेशन/प्रोग्राम को हमेशा इनपुट के प्रति उत्तरदायी होने की अनुमति देता है, भले ही वह पहले से ही कुछ पृष्ठभूमि कार्य चला रहा हो;
  2. मल्टीथ्रेडिंग कार्यों को तेज़ी से पूरा करना संभव बनाता है, क्योंकि थ्रेड्स स्वतंत्र रूप से चलते हैं;
  3. मल्टीथ्रेडिंग कैश मेमोरी का बेहतर उपयोग प्रदान करता है, क्योंकि थ्रेड्स साझा मेमोरी संसाधनों तक पहुंच सकते हैं;
  4. मल्टीथ्रेडिंग आवश्यक सर्वरों की संख्या को कम कर देता है, क्योंकि एक सर्वर एक साथ कई थ्रेड चला सकता है।

27. थ्रेड के जीवन चक्र में कौन सी अवस्थाएं होती हैं?

जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर।  भाग 2 - 3
  1. नया: इस स्थिति में, नए ऑपरेटर का उपयोग करके थ्रेड ऑब्जेक्ट बनाया जाता है, लेकिन एक नया थ्रेड अभी तक मौजूद नहीं है। जब तक हम स्टार्ट () विधि को कॉल नहीं करते तब तक थ्रेड शुरू नहीं होता है ।
  2. चलने योग्य: इस स्थिति में, धागा प्रारंभ के बाद चलने के लिए तैयार है () पद्धति कहलाती है। हालाँकि, इसे अभी तक थ्रेड शेड्यूलर द्वारा नहीं चुना गया है।
  3. चल रहा है: इस स्थिति में, थ्रेड शेड्यूलर तैयार स्थिति से एक थ्रेड चुनता है, और यह चलता है।
  4. प्रतीक्षा/अवरुद्ध: इस स्थिति में, एक थ्रेड नहीं चल रहा है, लेकिन यह अभी भी जीवित है या किसी अन्य थ्रेड के पूरा होने की प्रतीक्षा कर रहा है।
  5. डेड/टर्मिनेटेड: जब कोई थ्रेड रन () मेथड से बाहर निकलता है, तो वह डेड या टर्मिनेटेड स्थिति में होता है।

28. क्या एक धागे को दो बार चलाना संभव है?

नहीं, हम एक थ्रेड को फिर से शुरू नहीं कर सकते, क्योंकि एक थ्रेड के शुरू होने और चलने के बाद, यह डेड स्टेट में चला जाता है। यदि हम एक थ्रेड को दो बार शुरू करने का प्रयास करते हैं, तो java.lang.IllegalThreadStateException को फेंक दिया जाएगा। चलो एक नज़र मारें:
class DoubleStartThreadExample extends Thread {

   /**
    * Simulate the work of a thread
    */
   public void run() {
	// Something happens. At this state, this is not essential.
   }

   /**
    * Start the thread twice
    */
   public static void main(String[] args) {
       DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
       doubleStartThreadExample.start();
       doubleStartThreadExample.start();
   }
}
एक ही थ्रेड की दूसरी शुरुआत में निष्पादन आते ही एक अपवाद होगा। इसे स्वयं आज़माएं;) इसके बारे में सौ बार सुनने से बेहतर है कि इसे एक बार देख लिया जाए।

29. क्या होगा यदि आप स्टार्ट () को कॉल किए बिना सीधे रन () कहते हैं?

हां, आप निश्चित रूप से रन () विधि को कॉल कर सकते हैं, लेकिन एक नया थ्रेड नहीं बनाया जाएगा, और यह विधि एक अलग थ्रेड पर नहीं चलेगी। इस मामले में, हमारे पास सामान्य विधि को कॉल करने वाली एक सामान्य वस्तु है। अगर हम स्टार्ट () विधि के बारे में बात कर रहे हैं, तो यह दूसरी बात है। जब इस मेथड को कॉल किया जाता है, तो JVM एक नया थ्रेड शुरू करता है। यह धागा, बदले में, हमारी पद्धति को कॉल करता है;) विश्वास नहीं होता? यहाँ, इसे आजमाएँ:
class ThreadCallRunExample extends Thread {

   public void run() {
       for (int i = 0; i < 5; i++) {
           System.out.print(i);
       }
   }

   public static void main(String args[]) {
       ThreadCallRunExample runExample1 = new ThreadCallRunExample();
       ThreadCallRunExample runExample2 = new ThreadCallRunExample();

       // Two ordinary methods will be called in the main thread, one after the other.
       runExample1.run();
       runExample2.run();
   }
}
और कंसोल आउटपुट इस तरह दिखेगा:
0123401234
जैसा कि आप देख सकते हैं, कोई धागा नहीं बनाया गया था। सब कुछ एक सामान्य वर्ग की तरह ही काम करता था। सबसे पहले, पहली वस्तु की विधि निष्पादित की गई, और फिर दूसरी।

30. डेमन थ्रेड क्या है?

एक डेमन थ्रेड एक थ्रेड है जो किसी अन्य थ्रेड की तुलना में कम प्राथमिकता पर कार्य करता है। दूसरे शब्दों में, इसका काम उन सहायक कार्यों को करना है जिन्हें केवल दूसरे (मुख्य) थ्रेड के संयोजन में करने की आवश्यकता होती है। ऐसे कई डेमन थ्रेड हैं जो स्वचालित रूप से चलते हैं, जैसे कि कचरा संग्रहण, फ़ाइनलाइज़र, आदि।

जावा डेमन थ्रेड को क्यों समाप्त करता है?

डेमन थ्रेड का एकमात्र उद्देश्य उपयोगकर्ता के थ्रेड को पृष्ठभूमि समर्थन प्रदान करना है। तदनुसार, यदि मुख्य थ्रेड समाप्त हो जाता है, तो JVM स्वचालित रूप से अपने सभी डेमन थ्रेड्स को समाप्त कर देता है।

थ्रेड क्लास के तरीके

Java.lang.Thread क्लास डेमन थ्रेड के साथ काम करने के लिए दो तरीके प्रदान करता है :
  1. सार्वजनिक शून्य सेटडेमन (बूलियन स्थिति) - यह विधि इंगित करती है कि क्या यह एक डेमन थ्रेड होगा। डिफ़ॉल्ट गलत है । इसका मतलब यह है कि जब तक आप विशेष रूप से ऐसा नहीं कहते हैं, तब तक कोई डेमन थ्रेड नहीं बनाया जाएगा।
  2. सार्वजनिक बूलियन isDaemon () - यह विधि अनिवार्य रूप से डेमन चर के लिए एक गेट्टर है, जिसे हम पिछली विधि का उपयोग करके सेट करते हैं।
उदाहरण:
class DaemonThreadExample extends Thread {

   public void run() {
       // Checks whether this thread is a daemon
       if (Thread.currentThread().isDaemon()) {
           System.out.println("daemon thread");
       } else {
           System.out.println("user thread");
       }
   }

   public static void main(String[] args) {
       DaemonThreadExample thread1 = new DaemonThreadExample();
       DaemonThreadExample thread2 = new DaemonThreadExample();
       DaemonThreadExample thread3 = new DaemonThreadExample();

       // Make thread1 a daemon thread.
       thread1.setDaemon(true);

       System.out.println("daemon? " + thread1.isDaemon());
       System.out.println("daemon? " + thread2.isDaemon());
       System.out.println("daemon? " + thread3.isDaemon());

       thread1.start();
       thread2.start();
       thread3.start();
   }
}
कंसोल आउटपुट:
दानव? सच्चा दानव? झूठा दानव? झूठे डेमन थ्रेड उपयोगकर्ता थ्रेड उपयोगकर्ता थ्रेड
आउटपुट से, हम देखते हैं कि थ्रेड के अंदर ही, हम यह पता लगाने के लिए स्टैटिक करेंटथ्रेड () विधि का उपयोग कर सकते हैं कि यह कौन सा थ्रेड है। वैकल्पिक रूप से, यदि हमारे पास थ्रेड ऑब्जेक्ट का संदर्भ है, तो हम उससे सीधे पता लगा सकते हैं। यह विन्यास का आवश्यक स्तर प्रदान करता है।

31. क्या किसी थ्रेड को बनाने के बाद उसे डेमन बनाना संभव है?

नहीं। यदि आप ऐसा करने का प्रयास करते हैं, तो आपको IllegalThreadStateException मिलेगा । इसका मतलब है कि हम शुरू होने से पहले केवल एक डेमन थ्रेड बना सकते हैं। उदाहरण:
class SetDaemonAfterStartExample extends Thread {

   public void run() {
       System.out.println("Working...");
   }

   public static void main(String[] args) {
       SetDaemonAfterStartExample afterStartExample = new SetDaemonAfterStartExample();
       afterStartExample.start();

       // An exception will be thrown here
       afterStartExample.setDaemon(true);
   }
}
कंसोल आउटपुट:
काम करना ... धागे में अपवाद "मुख्य" java.lang.IllegalThreadStateException java.lang.Thread.setDaemon(Thread.java:1359) पर SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java:14) पर

32. शटडाउन हुक क्या है?

शटडाउन हुक एक थ्रेड है जिसे जावा वर्चुअल मशीन (JVM) के बंद होने से पहले कहा जाता है। इस प्रकार, जब जावा वर्चुअल मशीन सामान्य या असामान्य रूप से बंद हो जाती है, तो हम इसका उपयोग किसी संसाधन को जारी करने या राज्य को बचाने के लिए कर सकते हैं। हम निम्नलिखित विधि का उपयोग करके शटडाउन हुक जोड़ सकते हैं:
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
जैसा कि उदाहरण में दिखाया गया है:
/**
* A program that shows how to start a shutdown hook thread,
* which will be executed right before the JVM shuts down
*/
class ShutdownHookThreadExample extends Thread {

   public void run() {
       System.out.println("shutdown hook executed");
   }

   public static void main(String[] args) {

       Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());

       System.out.println("Now the program is going to fall asleep. Press Ctrl+C to terminate it.");
       try {
           Thread.sleep(60000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
}
कंसोल आउटपुट:
अब कार्यक्रम सोने जा रहा है। इसे समाप्त करने के लिए Ctrl+C दबाएं। शटडाउन हुक निष्पादित

33. तुल्यकालन क्या है?

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

एक विधि सिंक्रनाइज़ करना

किसी साझा संसाधन के लिए किसी ऑब्जेक्ट को लॉक करने के लिए एक सिंक्रनाइज़ विधि का उपयोग किया जाता है। जब कोई थ्रेड सिंक्रोनाइज़्ड मेथड को कॉल करता है, तो यह स्वचालित रूप से ऑब्जेक्ट के लॉक को प्राप्त कर लेता है और जब थ्रेड अपना कार्य पूरा कर लेता है तो इसे रिलीज़ कर देता है। यह काम करने के लिए, आपको सिंक्रोनाइज़्ड कीवर्ड जोड़ना होगा । हम एक उदाहरण देखकर देख सकते हैं कि यह कैसे काम करता है:
/**
* An example where we synchronize a method. That is, we add the synchronized keyword to it.
* There are two authors who want to use one printer. Each of them has composed their own poems
* And of course they don’t want their poems mixed up. Instead, they want work to be performed in * * * order for each of them
*/
class Printer {

   synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {
       // One object for two threads
       Printer printer  = new Printer();

       // Create two threads
       Writer1 writer1 = new Writer1(printer);
       Writer2 writer2 = new Writer2(printer);

       // Start them
       writer1.start();
       writer2.start();
   }
}

/**
* Author No. 1, who writes an original poem.
*/
class Writer1 extends Thread {
   Printer printer;

   Writer1(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<string> poem = Arrays.asList("I ", this.getName(), " Write", " A Letter");
       printer.print(poem);
   }

}

/**
* Author No. 2, who writes an original poem.
*/
class Writer2 extends Thread {
   Printer printer;

   Writer2(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<String> poem = Arrays.asList("I Do Not ", this.getName(), " Not Write", " No Letter");
       printer.print(poem);
   }
}
और कंसोल आउटपुट यह है:
मैं थ्रेड-0 एक पत्र लिखो मैं थ्रेड-1 नहीं लिखता कोई पत्र नहीं

तुल्यकालन ब्लॉक

एक विधि में किसी विशेष संसाधन पर सिंक्रनाइज़ेशन करने के लिए एक सिंक्रनाइज़ ब्लॉक का उपयोग किया जा सकता है। मान लीजिए कि एक बड़ी विधि में (हाँ, आपको उन्हें नहीं लिखना चाहिए, लेकिन कभी-कभी ऐसा होता है) आपको किसी कारण से केवल एक छोटे से खंड को सिंक्रनाइज़ करने की आवश्यकता होती है। यदि आप सभी विधि के कोड को सिंक्रनाइज़ ब्लॉक में रखते हैं, तो यह सिंक्रनाइज़ विधि के समान ही काम करेगा। वाक्य रचना इस तरह दिखती है:
synchronized ("object to be locked") {
   // The code that must be protected
}
पिछले उदाहरण को दोहराने से बचने के लिए, हम अनाम वर्गों का उपयोग करके थ्रेड्स बनाएंगे, अर्थात हम रननेबल इंटरफ़ेस को तुरंत लागू करेंगे।
/**
* This is how a synchronization block is added.
* Inside the block, you need to specify which object's mutex will be acquired.
*/
class Printer {

   void print(List<String> wordsToPrint) {
       synchronized (this) {
           wordsToPrint.forEach(System.out::print);
       }
       System.out.println();
   }

   public static void main(String args[]) {
       // One object for two threads
       Printer printer = new Printer();

       // Create two threads
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I ", "Writer1", " Write", " A Letter");
               printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I Do Not ", "Writer2", " Not Write", " No Letter");
               printer.print(poem);
           }
       });

       // Start them
       writer1.start();
       writer2.start();
   }
}

}
और कंसोल आउटपुट यह है:
मैं लेखक 1 पत्र लिखता हूँ मैं लेखक नहीं 2 पत्र नहीं लिखता हूँ

स्थैतिक तुल्यकालन

यदि आप एक स्थिर विधि को सिंक्रनाइज़ करते हैं, तो लॉकिंग क्लास पर होगी, ऑब्जेक्ट पर नहीं। इस उदाहरण में, हम स्टैटिक विधि में सिंक्रोनाइज़्ड कीवर्ड को लागू करके स्टैटिक सिंक्रोनाइज़ेशन करते हैं:
/**
* This is how a synchronization block is added.
* Inside the block, you need to specify which object's mutex will be acquired.
*/
class Printer {

   static synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {

       // Create two threads
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I ", "Writer1", " Write", " A Letter");
               Printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I Do Not ", "Writer2", " Not Write", " No Letter");
               Printer.print(poem);
           }
       });

       // Start them
       writer1.start();
       writer2.start();
   }
}
और कंसोल आउटपुट यह है:
मैं लेखक नहीं हूँ 2 नहीं लिखता हूँ कोई पत्र नहीं मैं लेखक 1 पत्र लिखता हूँ

34. अस्थिर चर क्या है?

मल्टीथ्रेडेड प्रोग्रामिंग में, थ्रेड सुरक्षा के लिए अस्थिर कीवर्ड का उपयोग किया जाता है। जब एक परिवर्तनशील चर को संशोधित किया जाता है, तो परिवर्तन अन्य सभी थ्रेड्स को दिखाई देता है, इसलिए एक समय में एक थ्रेड द्वारा एक चर का उपयोग किया जा सकता है। वाष्पशील कीवर्ड का उपयोग करके , आप गारंटी दे सकते हैं कि एक चर थ्रेड-सुरक्षित है और साझा मेमोरी में संग्रहीत है, और थ्रेड्स इसे अपने कैश में संग्रहीत नहीं करेंगे। यह किसकी तरह दिखता है?
private volatile AtomicInteger count;
हम सिर्फ वेरिएबल में वोलेटाइल जोड़ते हैं। लेकिन ध्यान रखें कि इसका मतलब पूर्ण थ्रेड सुरक्षा नहीं है... आखिरकार, चर पर संचालन परमाणु नहीं हो सकता है। उस ने कहा, आप परमाणु कक्षाओं का उपयोग कर सकते हैं जो परमाणु रूप से संचालन करते हैं, यानी एक सीपीयू निर्देश में। Java.util.concurrent.atomic पैकेज में ऐसे कई वर्ग हैं ।

35. डेडलॉक क्या है?

जावा में, डेडलॉक कुछ ऐसा है जो मल्टीथ्रेडिंग के हिस्से के रूप में हो सकता है। एक गतिरोध तब हो सकता है जब एक थ्रेड किसी अन्य थ्रेड द्वारा अधिग्रहित ऑब्जेक्ट के लॉक की प्रतीक्षा कर रहा हो, और दूसरा थ्रेड पहले थ्रेड द्वारा अधिग्रहित ऑब्जेक्ट के लॉक की प्रतीक्षा कर रहा हो। इसका मतलब है कि दो धागे एक-दूसरे की प्रतीक्षा कर रहे हैं और उनके कोड का निष्पादन जारी नहीं रह सकता है। जावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर।  भाग 2 - 4आइए एक उदाहरण पर विचार करें जिसमें एक वर्ग है जो रननेबल को लागू करता है। इसके कंस्ट्रक्टर को दो संसाधन लगते हैं। रन () विधि क्रम में उनके लिए लॉक प्राप्त करती है। यदि आप इस वर्ग की दो वस्तुएँ बनाते हैं, और संसाधनों को एक अलग क्रम में पास करते हैं, तो आप आसानी से गतिरोध में भाग सकते हैं:
class DeadLock {

   public static void main(String[] args) {
       final Integer r1 = 10;
       final Integer r2 = 15;

       DeadlockThread threadR1R2 = new DeadlockThread(r1, r2);
       DeadlockThread threadR2R1 = new DeadlockThread(r2, r1);

       new Thread(threadR1R2).start();
       new Thread(threadR2R1).start();
   }
}

/**
* A class that accepts two resources.
*/
class DeadlockThread implements Runnable {

   private final Integer r1;
   private final Integer r2;

   public DeadlockThread(Integer r1, Integer r2) {
       this.r1 = r1;
       this.r2 = r2;
   }

   @Override
   public void run() {
       synchronized (r1) {
           System.out.println(Thread.currentThread().getName() + " acquired resource: " + r1);

           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }

           synchronized (r2) {
               System.out.println(Thread.currentThread().getName() + " acquired resource: " + r2);
           }
       }
   }
}
कंसोल आउटपुट:
पहले थ्रेड ने पहला रिसोर्स हासिल किया दूसरा थ्रेड ने दूसरा रिसोर्स हासिल किया

36. आप गतिरोध से कैसे बचते हैं?

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

37. दौड़ की स्थिति क्या है?

यदि वास्तविक जीवन की दौड़ में कारें शामिल होती हैं, तो मल्टीथ्रेडिंग में दौड़ में धागे शामिल होते हैं। लेकिन क्यों? :/दो थ्रेड हैं जो चल रहे हैं और एक ही ऑब्जेक्ट तक पहुंच सकते हैं। और वे एक ही समय में साझा की गई वस्तु की स्थिति को अद्यतन करने का प्रयास कर सकते हैं। अब तक सब कुछ स्पष्ट है, है ना? थ्रेड्स को या तो शाब्दिक रूप से समानांतर (यदि प्रोसेसर में एक से अधिक कोर हैं) या क्रमिक रूप से निष्पादित किया जाता है, जिसमें प्रोसेसर इंटरलीव्ड टाइम स्लाइस आवंटित करता है। हम इन प्रक्रियाओं का प्रबंधन नहीं कर सकते। इसका मतलब यह है कि जब एक थ्रेड किसी ऑब्जेक्ट से डेटा पढ़ता है तो हम गारंटी नहीं दे सकते कि किसी अन्य थ्रेड के ऐसा करने से पहले उसके पास ऑब्जेक्ट को बदलने का समय होगा। ऐसी समस्याएँ तब उत्पन्न होती हैं जब हमारे पास ये "चेक-एंड-एक्ट" कॉम्बो होते हैं। इसका क्या मतलब है? मान लीजिए कि हमारे पास एक इफ स्टेटमेंट है, जिसका शरीर इफ-कंडीशन को ही बदल देता है, उदाहरण के लिए:
int z = 0;

// Check
if (z < 5) {
// Act
   z = z + 5;
}
दो धागे एक साथ इस कोड ब्लॉक में प्रवेश कर सकते हैं जब z अभी भी शून्य है और फिर दोनों धागे इसके मान को बदल सकते हैं। नतीजतन, हमें 5 का अपेक्षित मूल्य नहीं मिलेगा। इसके बजाय, हमें 10 मिलेगा। आप इससे कैसे बच सकते हैं? जाँचने और कार्य करने से पहले आपको एक ताला प्राप्त करना होगा, और उसके बाद ताला जारी करना होगा। यही है, आपको पहले थ्रेड को if ब्लॉक में प्रवेश करने की आवश्यकता है, सभी क्रियाएं करें, z को बदलें , और उसके बाद ही अगले थ्रेड को ऐसा करने का अवसर दें। लेकिन अगला थ्रेड if ब्लॉक में प्रवेश नहीं करेगा, क्योंकि z अब 5 होगा:
// Acquire the lock for z
if (z < 5) {
   z = z + 5;
}
// Release z's lock
===================================================

एक निष्कर्ष के बजाय

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

और हमेशा की तरह, यहाँ कुछ उपयोगी लिंक दिए गए हैं:

पढ़ने के लिए आप सभी का धन्यवाद। जल्द ही मिलते हैं :) मेरा गिटहब प्रोफाइलजावा कोर के लिए शीर्ष 50 नौकरी के साक्षात्कार प्रश्न और उत्तर।  भाग 2 - 5
टिप्पणियां
  • लोकप्रिय
  • नया
  • पुराना
टिप्पणी लिखने के लिए आपको साइन इन करना होगा
इस पेज पर अभी तक कोई टिप्पणियां नहीं हैं