CodeGym /Java Blog /यादृच्छिक /जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे. ...
John Squirrels
पातळी 41
San Francisco

जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे. भाग 2

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे. भाग 1जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे.  भाग २ - १

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

24. मी Java मध्ये नवीन थ्रेड कसा तयार करू?

एक किंवा दुसर्या मार्गाने, थ्रेड क्लास वापरून थ्रेड तयार केला जातो. पण हे करण्याचे विविध मार्ग आहेत...
  1. java.lang.Thread इनहेरिट करा .
  2. java.lang.Runnable इंटरफेस लागू करा — थ्रेड क्लासचा कन्स्ट्रक्टर रन करण्यायोग्य ऑब्जेक्ट घेतो.
चला त्या प्रत्येकाबद्दल बोलूया.

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

या प्रकरणात, आम्ही आमच्या वर्गाला java.lang.Thread वारसा बनवतो . यात एक रन() पद्धत आहे, आणि आपल्याला तेच हवे आहे. नवीन धाग्याचे सर्व जीवन आणि तर्क या पद्धतीत असतील. नवीन धाग्यासाठी ही एक मुख्य पद्धत आहे . त्यानंतर, आमच्या वर्गाचा एक ऑब्जेक्ट तयार करणे आणि start() पद्धत कॉल करणे बाकी आहे. हे एक नवीन धागा तयार करेल आणि त्याचे तर्क कार्य करण्यास सुरवात करेल. चला पाहुया:

/**
* 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
म्हणजेच, येथेही आपण पाहतो की थ्रेड्स क्रमाने चालवल्या जात नाहीत, तर JVM त्यांना चालवण्यासाठी योग्य वाटतात :)

रन करण्यायोग्य इंटरफेस लागू करा

तुम्ही वारसाच्या विरोधात असाल आणि/किंवा आधीपासून काही इतर वर्गाचे वारसा घेतल्यास, तुम्ही 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 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे.  भाग २ - २प्रक्रिया आणि धागा खालील प्रकारे भिन्न आहेत:
  1. चालू असलेल्या प्रोग्रामला प्रक्रिया म्हणतात, परंतु थ्रेड हा प्रक्रियेचा एक भाग असतो.
  2. प्रक्रिया स्वतंत्र आहेत, परंतु धागे हे प्रक्रियेचे तुकडे आहेत.
  3. प्रक्रियांमध्ये मेमरीमध्ये वेगवेगळ्या पत्त्याच्या जागा असतात, परंतु थ्रेड्समध्ये एक सामान्य अॅड्रेस स्पेस असते.
  4. थ्रेड दरम्यान संदर्भ स्विचिंग प्रक्रियांमध्ये स्विच करण्यापेक्षा वेगवान आहे.
  5. आंतर-प्रक्रिया संप्रेषण आंतर-थ्रेड संप्रेषणापेक्षा हळू आणि अधिक महाग आहे.
  6. पालक प्रक्रियेतील कोणतेही बदल मुलाच्या प्रक्रियेवर परिणाम करत नाहीत, परंतु पालक थ्रेडमधील बदल चाइल्ड थ्रेडवर परिणाम करू शकतात.

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

  1. मल्टीथ्रेडिंग ॲप्लिकेशन/प्रोग्रामला नेहमी इनपुटला प्रतिसाद देण्यास अनुमती देते, जरी ते आधीपासून काही पार्श्वभूमी कार्ये चालवत असले तरीही;
  2. मल्टीथ्रेडिंगमुळे कार्ये जलद पूर्ण करणे शक्य होते, कारण थ्रेड स्वतंत्रपणे चालतात;
  3. मल्टीथ्रेडिंग कॅशे मेमरीचा अधिक चांगला वापर प्रदान करते, कारण थ्रेड्स सामायिक मेमरी संसाधनांमध्ये प्रवेश करू शकतात;
  4. मल्टीथ्रेडिंगमुळे आवश्यक सर्व्हरची संख्या कमी होते, कारण एक सर्व्हर एकाच वेळी अनेक थ्रेड चालवू शकतो.

27. धाग्याच्या जीवन चक्रातील अवस्था काय आहेत?

जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे.  भाग 2 - 3
  1. नवीन: या स्थितीत, नवीन ऑपरेटर वापरून थ्रेड ऑब्जेक्ट तयार केला जातो, परंतु नवीन थ्रेड अद्याप अस्तित्वात नाही. जोपर्यंत आपण start() पद्धत कॉल करत नाही तोपर्यंत थ्रेड सुरू होत नाही .
  2. रन करण्यायोग्य: या स्थितीत, थ्रेड start() नंतर चालण्यासाठी तयार आहे पद्धत म्हणतात. तथापि, ते अद्याप थ्रेड शेड्यूलरने निवडलेले नाही.
  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();
   }
}
त्याच धाग्याच्या दुसर्‍या स्टार्टवर एक्झिक्यूशन येताच अपवाद असेल. हे स्वतः करून पहा ;) शंभर वेळा ऐकण्यापेक्षा हे एकदा पाहणे चांगले.

२९. तुम्ही start() ला कॉल न करता थेट run() कॉल केल्यास काय होईल?

होय, तुम्ही रन() पद्धतीला नक्कीच कॉल करू शकता , परंतु नवीन थ्रेड तयार केला जाणार नाही आणि ही पद्धत वेगळ्या धाग्यावर चालणार नाही. या प्रकरणात, आमच्याकडे एक सामान्य ऑब्जेक्ट आहे जी सामान्य पद्धत कॉल करते. जर आपण start() पद्धतीबद्दल बोलत आहोत, तर ती दुसरी बाब आहे. जेव्हा ही पद्धत कॉल केली जाते, तेव्हा 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();
   }
}
आणि कन्सोल आउटपुट असे दिसेल:
०१२३४०१२३४
तुम्ही बघू शकता, कोणताही धागा तयार झाला नाही. सर्व काही सामान्य वर्गाप्रमाणेच चालले. प्रथम, पहिल्या ऑब्जेक्टची पद्धत अंमलात आणली गेली आणि नंतर दुसरी.

30. डिमन थ्रेड म्हणजे काय?

डिमन थ्रेड हा एक धागा आहे जो इतर थ्रेडपेक्षा कमी प्राधान्याने कार्य करतो. दुसऱ्या शब्दांत, त्याचे कार्य सहायक कार्ये करणे आहे जे फक्त दुसर्या (मुख्य) थ्रेडच्या संयोगाने करणे आवश्यक आहे. अनेक डिमन थ्रेड्स आहेत जे आपोआप चालतात, जसे की कचरा गोळा करणे, फायनलायझर इ.

Java डिमन थ्रेड का बंद करते?

डिमन थ्रेडचा एकमेव उद्देश वापरकर्त्याच्या थ्रेडला पार्श्वभूमी समर्थन प्रदान करणे आहे. त्यानुसार, मुख्य थ्रेड संपुष्टात आणल्यास, JVM आपोआप त्याचे सर्व डिमन थ्रेड्स संपुष्टात आणते.

थ्रेड वर्गाच्या पद्धती

java.lang.Thread वर्ग डिमन थ्रेडसह कार्य करण्यासाठी दोन पद्धती प्रदान करतो :
  1. public void setDaemon(बूलियन स्टेटस) — ही पद्धत दर्शवते की हा डिमन थ्रेड असेल. डीफॉल्ट खोटे आहे . याचा अर्थ असा की जोपर्यंत तुम्ही विशेषत: असे म्हणत नाही तोपर्यंत कोणतेही डिमन धागे तयार केले जाणार नाहीत.
  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);
   }
}
कन्सोल आउटपुट:
कार्यरत... SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java) येथे java.lang.Thread.setDaemon(Thread.java:1359) येथे "मुख्य" java.lang.IllegalThreadStateException थ्रेडमधील अपवाद:14

32. शटडाउन हुक म्हणजे काय?

शटडाउन हुक हा एक धागा आहे जो Java व्हर्च्युअल मशीन (JVM) बंद होण्यापूर्वी स्पष्टपणे कॉल केला जातो. अशा प्रकारे, जेव्हा Java व्हर्च्युअल मशीन सामान्यपणे किंवा असामान्यपणे बंद होते तेव्हा आम्ही संसाधन सोडण्यासाठी किंवा स्थिती जतन करण्यासाठी वापरू शकतो. आम्ही खालील पद्धत वापरून शटडाउन हुक जोडू शकतो :

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. सिंक्रोनाइझेशन म्हणजे काय?

Java मध्ये, सिंक्रोनाइझेशन ही कोणत्याही सामायिक संसाधनावर एकाधिक थ्रेड्सचा प्रवेश नियंत्रित करण्याची क्षमता आहे. जेव्हा अनेक थ्रेड्स एकाच वेळी समान कार्य करण्याचा प्रयत्न करतात, तेव्हा तुम्हाला चुकीचा परिणाम मिळू शकतो. या समस्येचे निराकरण करण्यासाठी, Java सिंक्रोनाइझेशन वापरते, जे एका वेळी फक्त एक थ्रेड चालवण्यास अनुमती देते. सिंक्रोनाइझेशन तीन प्रकारे केले जाऊ शकते:
  • पद्धत सिंक्रोनाइझ करणे
  • विशिष्ट ब्लॉक सिंक्रोनाइझ करणे
  • स्थिर सिंक्रोनाइझेशन

पद्धत सिंक्रोनाइझ करणे

कोणत्याही सामायिक संसाधनासाठी ऑब्जेक्ट लॉक करण्यासाठी सिंक्रोनाइझ केलेली पद्धत वापरली जाते. जेव्हा एखादा थ्रेड सिंक्रोनाइझ केलेल्या पद्धतीवर कॉल करतो, तेव्हा तो ऑब्जेक्टचे लॉक आपोआप मिळवतो आणि जेव्हा थ्रेड त्याचे कार्य पूर्ण करतो तेव्हा तो सोडतो. हे कार्य करण्यासाठी, तुम्हाला सिंक्रोनाइझ केलेला कीवर्ड जोडणे आवश्यक आहे. एक उदाहरण पाहून हे कसे कार्य करते ते आपण पाहू शकतो:

/**
* 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;
आम्ही व्हेरिएबलमध्ये फक्त अस्थिर जोडतो. परंतु लक्षात ठेवा की याचा अर्थ संपूर्ण धागा सुरक्षितता असा नाही... शेवटी, व्हेरिएबलवरील ऑपरेशन्स अणू असू शकत नाहीत. असे म्हटले आहे की, तुम्ही अणू वर्ग वापरू शकता जे अणू पद्धतीने ऑपरेशन करतात, म्हणजे एकाच CPU निर्देशामध्ये. java.util.concurrent.atomic पॅकेजमध्ये असे अनेक वर्ग आहेत .

35. डेडलॉक म्हणजे काय?

Java मध्ये, डेडलॉक अशी गोष्ट आहे जी मल्टीथ्रेडिंगचा भाग म्हणून होऊ शकते. जेव्हा एखादा थ्रेड दुसर्‍या थ्रेडद्वारे मिळवलेल्या ऑब्जेक्टच्या लॉकची वाट पाहत असतो आणि दुसरा थ्रेड पहिल्या थ्रेडद्वारे मिळवलेल्या ऑब्जेक्टच्या लॉकची वाट पाहत असतो तेव्हा डेडलॉक होऊ शकतो. याचा अर्थ असा की दोन धागे एकमेकांची वाट पाहत आहेत आणि त्यांच्या कोडची अंमलबजावणी सुरू ठेवू शकत नाही. जावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे.  भाग 2 - 4चला एक उदाहरण पाहू ज्यामध्ये Runnable लागू करणारा वर्ग आहे. त्याच्या कन्स्ट्रक्टरला दोन संसाधने लागतात. रन() पद्धत क्रमाने त्यांच्यासाठी लॉक मिळवते. जर तुम्ही या वर्गाच्या दोन वस्तू तयार केल्या आणि संसाधने वेगळ्या क्रमाने पास केली, तर तुम्ही सहजपणे डेडलॉकमध्ये जाऊ शकता:

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. तुम्ही गतिरोध कसे टाळता?

कारण आम्हाला माहित आहे की गतिरोध कसा होतो, आम्ही काही निष्कर्ष काढू शकतो...
  • वरील उदाहरणामध्ये, आम्ही नेस्टेड लॉकिंग केले आहे या वस्तुस्थितीमुळे डेडलॉक उद्भवते. म्हणजेच, आमच्याकडे सिंक्रोनाइझ ब्लॉकच्या आत एक समक्रमित ब्लॉक आहे. हे टाळण्यासाठी, नेस्ट करण्याऐवजी, तुम्हाला नवीन उच्च अ‍ॅबस्ट्रॅक्शन लेयर तयार करणे आवश्यक आहे, सिंक्रोनाइझेशनला उच्च स्तरावर हलवावे लागेल आणि नेस्टेड लॉकिंग काढून टाकावे लागेल.
  • तुम्ही जितके जास्त लॉकिंग कराल तितके डेडलॉक होण्याची शक्यता जास्त आहे. म्हणून, प्रत्येक वेळी तुम्ही सिंक्रोनाइझ केलेला ब्लॉक जोडताना, तुम्हाला त्याची खरोखर गरज आहे का आणि तुम्ही नवीन जोडणे टाळू शकता का याचा विचार करणे आवश्यक आहे.
  • Thread.join() वापरणे . एक थ्रेड दुसर्‍याची वाट पाहत असताना तुम्ही डेडलॉकमध्ये देखील धावू शकता. ही समस्या टाळण्यासाठी, तुम्ही join() पद्धतीसाठी कालबाह्य ठरवण्याचा विचार करू शकता .
  • जर आमच्याकडे एक धागा असेल तर कोणतीही गतिरोध होणार नाही ;)

37. शर्यतीची स्थिती काय आहे?

वास्तविक जीवनातील शर्यतींमध्ये कारचा समावेश असेल, तर मल्टीथ्रेडिंगमधील शर्यतींमध्ये थ्रेडचा समावेश होतो. पण का? :/ दोन थ्रेड्स चालू आहेत आणि एकाच ऑब्जेक्टमध्ये प्रवेश करू शकतात. आणि ते त्याच वेळी सामायिक केलेल्या ऑब्जेक्टची स्थिती अद्यतनित करण्याचा प्रयत्न करू शकतात. आतापर्यंत सर्व काही स्पष्ट आहे, बरोबर? थ्रेड्स एकतर अक्षरशः समांतर (जर प्रोसेसरमध्ये एकापेक्षा जास्त कोर असतील) किंवा क्रमाक्रमाने, प्रोसेसर इंटरलीव्ह टाइम स्लाइस वाटप करून कार्यान्वित केले जातात. आम्ही या प्रक्रिया व्यवस्थापित करू शकत नाही. याचा अर्थ असा की जेव्हा एखादा थ्रेड एखाद्या ऑब्जेक्टमधील डेटा वाचतो तेव्हा आम्ही हमी देऊ शकत नाही की इतर थ्रेडने तसे करण्यापूर्वी ऑब्जेक्ट बदलण्यास वेळ मिळेल. जेव्हा आपल्याकडे हे "चेक-अँड-ऍक्ट" कॉम्बो असतात तेव्हा अशा समस्या उद्भवतात. याचा अर्थ काय? समजा आपल्याकडे एक if स्टेटमेंट आहे ज्याचा मुख्य भाग if-स्थिती बदलतो, उदाहरणार्थ:

int z = 0;

// Check
if (z < 5) {
// Act
   z = z + 5;
}
z अजूनही शून्य असताना दोन थ्रेड एकाच वेळी हा कोड ब्लॉक प्रविष्ट करू शकतात आणि नंतर दोन्ही थ्रेड त्याचे मूल्य बदलू शकतात. परिणामी, आम्हाला 5 चे अपेक्षित मूल्य मिळणार नाही. त्याऐवजी, आम्हाला 10 मिळेल. तुम्ही हे कसे टाळाल? तपासण्यापूर्वी आणि कृती करण्यापूर्वी तुम्हाला लॉक घेणे आवश्यक आहे आणि नंतर लॉक सोडणे आवश्यक आहे. म्हणजेच, तुम्हाला पहिला थ्रेड इफ ब्लॉक प्रविष्ट करणे आवश्यक आहे, सर्व क्रिया करा, z बदला आणि त्यानंतरच पुढील थ्रेडला ते करण्याची संधी द्या. परंतु पुढील थ्रेड if ब्लॉकमध्ये प्रवेश करणार नाही, कारण z आता 5 असेल:

// Acquire the lock for z
if (z < 5) {
   z = z + 5;
}
// Release z's lock
===================================================

निष्कर्षाऐवजी

मी शेवटपर्यंत वाचलेल्या प्रत्येकाचे आभार मानू इच्छितो. ते खूप लांब होते, परंतु तुम्ही सहन केले! कदाचित सर्व काही स्पष्ट नाही. हे सामान्य आहे. जेव्हा मी पहिल्यांदा Java चा अभ्यास करायला सुरुवात केली, तेव्हा स्टॅटिक व्हेरिएबल म्हणजे काय हे मी माझ्या मेंदूला गुंडाळू शकलो नाही. पण मोठी गोष्ट नाही. मी त्यावर झोपलो, आणखी काही स्रोत वाचले आणि मग समज आली. मुलाखतीची तयारी करणे हा व्यावहारिक प्रश्नापेक्षा शैक्षणिक प्रश्न आहे. परिणामी, प्रत्येक मुलाखतीपूर्वी, तुम्ही त्या गोष्टींचे पुनरावलोकन केले पाहिजे आणि तुमच्या स्मृतीमध्ये ताजेतवाने केले पाहिजे ज्यांचा तुम्ही सहसा वापर करत नाही.

आणि नेहमीप्रमाणे, येथे काही उपयुक्त दुवे आहेत:

वाचल्याबद्दल सर्वांचे आभार. लवकरच भेटू :) माझे GitHub प्रोफाइलजावा कोअरसाठी शीर्ष 50 जॉब इंटरव्ह्यू प्रश्न आणि उत्तरे.  भाग 2 - 5
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION