दिलचस्प पोस्ट
सीएसएस का उपयोग कर सही से एक पृष्ठभूमि की छवि ऑफसेट आम गेटवे इंटरफ़ेस (सीजीआई) क्या है? एक्लेप्से उपयोग के लिए साफ़कर प्लगइन क्या यह गैर-स्थिरता मानक पुस्तकालय कार्यों को constexpr के रूप में व्यवहार करने के लिए एक अनुरूप कम्पाइलर एक्सटेंशन है? एक जावास्क्रिप्ट ऑब्जेक्ट स्वयं के मानों को कैसे संदर्भित कर सकता है? मैं जावास्क्रिप्ट में ऑटोरेटेड किडेडाउन इवेंट्स से कैसे बच सकता हूं? JSON.net: डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग किए बिना कैसे deserialize करें? जेपीएनएल ने फिर से रंगना समस्या स्थानीय दिनांक में यूटीसी युग को परिवर्तित करें एरलांग में ट्रेस और डीबीजी का उपयोग करना सफ़ल पाठ 2 कंसोल इनपुट गिनती के साथ लंबे प्रारूप में लंबे समय तक कन्वर्ट करने का आसान तरीका स्थैतिक विधि को लागू करने के लिए कस्टम ईएल फ़ंक्शन कैसे बनाएं? JQuery के साथ JSON डेटा भेजें सी और सी + + टिप्पणियां निकालने के लिए पायथन स्निपेट

कैसे जावा Multithreading में CountDownLatch उपयोग किया जाता है?

क्या कोई मुझे यह समझने में सहायता करता है कि जावा CountDownLatch क्या है और इसका उपयोग कब किया जाए?

मेरे पास इस कार्यक्रम का काम करने का एक बहुत स्पष्ट विचार नहीं है। जैसा कि मैं समझता हूं कि तीनों धागे एक ही बार में शुरू होती हैं और प्रत्येक थ्रेड 3000 एमएमएस के बाद काउंटडाउनलाच को बुलाएगा। तो नीचे गिनती एक-एक करके कम हो जाएगी कुंडी शून्य हो जाने के बाद कार्यक्रम "पूर्ण" प्रिंट करता है शायद जिस तरह से मैंने समझा है वह गलत है।

 import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Processor implements Runnable { private CountDownLatch latch; public Processor(CountDownLatch latch) { this.latch = latch; } public void run() { System.out.println("Started."); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); } } 

// ———————————————— —–

 public class App { public static void main(String[] args) { CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0 ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool for(int i=0; i < 3; i++) { executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1 } try { latch.await(); // wait until latch counted down to 0 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Completed."); } } 

Solutions Collecting From Web of "कैसे जावा Multithreading में CountDownLatch उपयोग किया जाता है?"

हाँ, आप सही ढंग से समझ गए CountDownLatch लैच सिद्धांत में काम करती है, मुख्य धागा इंतजार करेंगे जब तक कि द्वार खुले नहीं हो। जावा में CountDownLatch बनाते समय एक धागा निर्दिष्ट किए गए धागे के एन नंबर के लिए प्रतीक्षा करता है

किसी भी थ्रेड, आमतौर पर आवेदन के मुख्य धागा, जो कि CountDownLatch.await() कॉल करता है जब तक कि गिनती शून्य तक पहुंचने के लिए या किसी दूसरे थ्रेड द्वारा बाधित होने तक प्रतीक्षा करेगी। अन्य सभी थ्रेड को पूरा करने या तैयार होने के बाद, CountDownLatch.countDown() को कॉल करके गणना करना आवश्यक है।

जैसे ही गिनती शून्य हो जाती है, थ्रेड का इंतजार करना शुरू हो रहा है। CountDownLatch के नुकसान / फायदों में से एक यह है कि यह शून्य से एक बार गिनती के बाद पुन: प्रयोज्य नहीं है, आप किसी भी अधिक गणना का उपयोग नहीं कर सकते।

संपादित करें:

CountDownLatch उपयोग करें जब मुख्य थ्रेड की तरह एक धागा को एक या एक से अधिक धागे के लिए इंतजार करना होगा, इससे पहले कि वह प्रसंस्करण शुरू कर सकें।

जावा में CountDownLatch का उपयोग करने का क्लासिकल उदाहरण किसी भी सर्वर साइड कोर जावा एप्लिकेशन है जो सर्विस आर्किटेक्चर का उपयोग करता है, जहां एकाधिक थ्रेड्स द्वारा कई सेवाएं प्रदान की जाती हैं और एप्लिकेशन प्रोसेसिंग शुरू नहीं कर सकता जब तक कि सभी सेवाओं को सफलतापूर्वक शुरू न हो जाए।

पीएस ओपी के सवाल का एक बहुत सरल उदाहरण है, इसलिए मैंने इसमें शामिल नहीं किया था

जावा में CountDownLatch एक प्रकार का तुल्यकालन है जो एक Thread को प्रसंस्करण शुरू होने से पहले एक या अधिक Thread लिए प्रतीक्षा करने की अनुमति देता है।

CountDownLatch लैच सिद्धांत पर काम करती है, द्वार खुले होने तक धागा इंतजार करता है। एक थ्रेड CountDownLatch बनाने के दौरान निर्दिष्ट धागे के n नंबर के लिए प्रतीक्षा करता है।

जैसे final CountDownLatch latch = new CountDownLatch(3);

यहाँ हम काउंटर को 3 पर सेट करें

कोई थ्रेड, आमतौर पर अनुप्रयोग का मुख्य CountDownLatch.await() , जो गणना करता है CountDownLatch.await() जब तक गिनती शून्य तक पहुंचने तक प्रतीक्षा करेगी या किसी दूसरे Thread द्वारा बाधित है। अन्य सभी थ्रेडों को गणना करने के लिए आवश्यक हैं कि उन्हें गणना के बाद CountDownLatch.countDown() को पूरा कर लिया जाता है या नौकरी के लिए तैयार हो जाता है। जैसे ही गिनती शून्य हो जाती है, Thread इंतजार करना शुरू हो रहा है।

यहां गिनती की गणना CountDownLatch.countDown() विधि से CountDownLatch.countDown()

Thread जो await() विधि कॉल await() जब तक आरंभिक गिनती तक शून्य तक नहीं पहुंच जाएगा

गिनती करने के लिए शून्य अन्य थ्रेड्स को countDown() विधि कॉल करने की आवश्यकता है। एक बार गिनती शून्य हो जाने पर धागा जो await() विधि फिर से शुरू होगी (इसकी निष्पादन शुरू करें)।

CountDownLatch का नुकसान यह है कि यह पुन: प्रयोज्य नहीं है: एक बार गिनती शून्य हो जाने के बाद अब यह प्रयोग करने योग्य नहीं है।

निकोलाब ने इसे बहुत अच्छी तरह से समझाया, लेकिन उदाहरण समझने में सहायक होगा, तो यहां एक सरल उदाहरण है …

  import java.util.concurrent.*; public class CountDownLatchExample { public static class ProcessThread implements Runnable { CountDownLatch latch; long workDuration; String name; public ProcessThread(String name, CountDownLatch latch, long duration){ this.name= name; this.latch = latch; this.workDuration = duration; } public void run() { try { System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds"); Thread.sleep(workDuration); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name+ "completed its works"); //when task finished.. count down the latch count... // basically this is same as calling lock object notify(), and object here is latch latch.countDown(); } } public static void main(String[] args) { // Parent thread creating a latch object CountDownLatch latch = new CountDownLatch(3); new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs System.out.println("waiting for Children processes to complete...."); try { //current thread will get notified if all chidren's are done // and thread will resume from wait() mode. latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("All Process Completed...."); System.out.println("Parent Thread Resuming work...."); } } 

इसका उपयोग तब किया जाता है जब हम अपने कार्य को पूरा करने के लिए एक से अधिक धागे की प्रतीक्षा करना चाहते हैं। यह धागे में शामिल होने के समान है।

हम काउंटडाउन लैच का उपयोग कर सकते हैं

एक परिदृश्य पर विचार करें जहां हमारे पास तीन धागे "ए", "बी" और "सी" हैं और हम "सी" धागा शुरू करना चाहते हैं, जब "ए" और "बी" धागे पूर्ण हो जाएंगे या आंशिक रूप से अपने कार्य को पूरा करेंगे।

यह वास्तविक दुनिया आईटी परिदृश्य पर लागू किया जा सकता है

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

 public class Manager { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(2); MyDevTeam teamDevA = new MyDevTeam(countDownLatch, "devA"); MyDevTeam teamDevB = new MyDevTeam(countDownLatch, "devB"); teamDevA.start(); teamDevB.start(); countDownLatch.await(); MyQATeam qa = new MyQATeam(); qa.start(); } } class MyDevTeam extends Thread { CountDownLatch countDownLatch; public MyDevTeam (CountDownLatch countDownLatch, String name) { super(name); this.countDownLatch = countDownLatch; } @Override public void run() { System.out.println("Task assigned to development team " + Thread.currentThread().getName()); try { Thread.sleep(2000); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("Task finished by development team Thread.currentThread().getName()); this.countDownLatch.countDown(); } } class MyQATeam extends Thread { @Override public void run() { System.out.println("Task assigned to QA team"); try { Thread.sleep(2000); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("Task finished by QA team"); } } 

उपरोक्त कोड का उत्पादन होगा:

विकास दल devB को सौंपा कार्य

विकास टीम देव को सौंपा कार्य

विकास टीम devB द्वारा कार्य समाप्त

विकास टीम देव द्वारा समाप्त कार्य

क्यूए टीम को सौंपा गया कार्य

क्यूए टीम द्वारा कार्य समाप्त

यहां इंतजार () विधि काउंटडाउनलच फ्लैग के लिए 0 बनने की प्रतीक्षा करता है, और countdown () विधि 1 से उलटी गिनती लच ध्वज घट जाती है

JOIN की सीमा: उदाहरण के साथ, JOIN के साथ भी प्राप्त किया जा सकता है, लेकिन JOIN का उपयोग दो परिदृश्यों में नहीं किया जा सकता है:

  1. जब हम सूत्र बनाने के लिए थ्रेड वर्ग के बजाय निष्पादक सेवा का उपयोग करते हैं।
  2. उदाहरण के अनुसार संशोधित करें जहां प्रबंधक क्यूए टीम को कोड सौंपना चाहता है जैसे ही डेवलपमेंट अपने 80% कार्य को पूरा करता है। इसका मतलब है कि गिनती लॉग हमें कार्यान्वयन को संशोधित करने की अनुमति देता है जिसका उपयोग उनके आंशिक निष्पादन के लिए दूसरे धागे के लिए इंतजार करने के लिए किया जा सकता है।

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

स्यूडोकोड:


 CountDownLatch latch; void writeData() { latch = new CountDownLatch(1); serialPort.writeBytes(sb.toString().getBytes()) try { latch.await(4, TimeUnit.SECONDS); } catch (InterruptedException e) { } } class SerialPortReader implements SerialPortEventListener { public void serialEvent(SerialPortEvent event) { if(event.isRXCHAR()){//If data is available byte buffer[] = serialPort.readBytes(event.getEventValue()); latch.countDown(); } } } 

CoundDownLatch आपको थ्रेड का इंतजार करने में सक्षम बनाता है जब तक अन्य निष्पादन के साथ अन्य थ्रेड्स नहीं किया जाता है।

छद्म कोड हो सकता है:

 // Main thread starts // Create CountDownLatch for N threads // Create and start N threads // Main thread waits on latch // N threads completes there tasks are returns // Main thread resume execution 

अगर आप अपनी कॉल को latch.countDown () के बाद कुछ डिबग जोड़ते हैं, तो इससे आपको उसके व्यवहार को बेहतर समझने में मदद मिल सकती है

 latch.countDown(); System.out.println("DONE "+this.latch); // Add this debug 

आउटपुट दिखाएगा कि गिनती कम हो रही है। यह 'गिनती' प्रभावी रूप से रननेबल कार्य (प्रोसेसर ऑब्जेक्ट्स) की संख्या है जिसे आपने शुरू किया है जिसके खिलाफ countdown () को लागू नहीं किया गया है और इसलिए मुख्य धागा को अपनी कॉल को latch.ait () पर अवरुद्ध कर दिया गया है।

 DONE java.util.concurrent.CountDownLatch@70e69696[Count = 2] DONE java.util.concurrent.CountDownLatch@70e69696[Count = 1] DONE java.util.concurrent.CountDownLatch@70e69696[Count = 0] 

गणना के बारे में ओकेल दस्तावेज से:

एक सिंक्रनाइज़ेशन सहायता जो एक या अधिक थ्रेड्स की प्रतीक्षा करता है जब तक अन्य धागे में पूर्ण किए जाने वाले ऑपरेशन के सेट पूर्ण नहीं हो जाते।

एक गणना गणना के साथ एक गणना CountDownLatch की गई है। countDown() विधि के आविष्कारों के कारण वर्तमान गिनती शून्य तक पहुंचने तक के तरीकों को रोकते हैं, जिसके बाद सभी इंतजार किए गए धागे जारी होते हैं और किसी भी बाद के आमंत्रण तुरंत वापसी का इंतजार करते हैं। यह एक-शॉट घटना है – गिनती रीसेट नहीं की जा सकती।

एक काउन्टडाउनलाच एक बहुमुखी तुल्यकालन उपकरण है और इसे कई प्रयोजनों के लिए इस्तेमाल किया जा सकता है।

एक की CountDownLatch साथ आरंभ किए जाने वाले एक CountDownLatch सरल / बंद कुंडी, या गेट के रूप में कार्य करता है: सभी थ्रेड्स जो कि एक धागा खोलने के लिए गेट डाउन ()

N के लिए CountDownLatch किया गया एक CountDownLatch , एक धागे का इंतजार करने के लिए इस्तेमाल किया जा सकता है जब तक कि एन थ्रेड्स ने कुछ कार्य पूरा नहीं किया हो, या कुछ कार्य पूर्ण हो गया है N बार

 public void await() throws InterruptedException 

वर्तमान थ्रेड को तब तक इंतजार करने के लिए होता है जब तक कि कुंडी को शून्य तक गिना न दिया जाए, जब तक कि थ्रेड बाधित न हो।

यदि वर्तमान गणना शून्य है तो यह विधि तुरंत वापस आता है।

 public void countDown() 

कुंडी की गिनती को घटाता है, सभी प्रतीक्षा थ्रेड्स जारी करते हैं यदि गिनती शून्य हो जाती है

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

आपके उदाहरण की व्याख्या

  1. आपने latch वैरिएबल के लिए गिनती 3 सेट की है

     CountDownLatch latch = new CountDownLatch(3); 
  2. आपने कार्यकर्ता धागा को यह साझा latch पारित किया है: Processor

  3. Processor तीन Runnable इंस्टेंसर्स को ExecutorService executor ExecutorService पास भेज दिया गया है
  4. मुख्य धागा ( App ) नीचे कथन के साथ शून्य होने के लिए गिनती की प्रतीक्षा कर रहा है

      latch.await(); 
  5. Processor थ्रेड 3 सेकंड के लिए सोता है और फिर यह latch.countDown() साथ गिनती मान latch.countDown()
  6. सबसे पहले Process उदाहरण latch.countDown() कारण पूरा होने के बाद latch.countDown() की संख्या 2 को बदल देगा।

  7. दूसरी Process उदाहरण, latch.countDown() कारण पूर्ण होने के बाद 1 के रूप में latch.countDown() गिन बदल जाएगा।

  8. तीसरा Process उदाहरण latch.countDown() कारण इसे पूर्ण होने के बाद 0 के रूप में latch.countDown() गिन बदल जाएगा।

  9. लेट पर ज़रा गिनती का await करने से मुख्य थैला App को बाहर आना पड़ता है

  10. ऐप प्रोग्राम इस आउटपुट को प्रिंट करता है: Completed

जैसा कि जावाडॉक ( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html ) में उल्लिखित है, काउल्टडाउनलाच एक सिंक्रनाइज़ेशन सहायता है, जो जावा 5 में पेश किया गया है। यहां सिंक्रनाइज़ेशन नहीं है एक महत्वपूर्ण खंड तक पहुँच सीमित करना बल्कि विभिन्न धागे के कार्यों को क्रमबद्ध करना गणना के प्रकार के माध्यम से प्राप्त सिंक्रनाइज़ेशन में शामिल होने के समान है। मान लें कि एक धागा "एम" है जो दूसरे वर्कर थ्रेड "T1", "T2", "T3" के लिए अपने कार्यों को पूरा करने के लिए इंतजार करना पड़ता है, जावा 1.5 से पहले, जिस तरह से यह किया जा सकता है, एम निम्नलिखित कोड चल रहा है T1.join(); T2.join(); T3.join(); T1.join(); T2.join(); T3.join();

उपरोक्त कोड यह सुनिश्चित करता है कि टी 1, टी 2, टी 3 के काम के बाद थ्रेड एम ने अपना काम शुरू कर दिया। टी 1, टी 2, टी 3 अपने काम को किसी भी क्रम में पूरा कर सकते हैं। एक ही गणना के माध्यम से प्राप्त किया जा सकता है, जहां टी 1, टी 2, टी 3 और धागा एम समान गणना वाले ऑब्जेक्ट को साझा करते हैं।
"एम" अनुरोध: countDownLatch.await();
जहां "टी 1", "टी 2", "टी 3" के रूप में countDownLatch.countdown(); करता है countDownLatch.countdown();

जुड़ने की विधि के साथ एक नुकसान यह है कि एम को टी 1, टी 2, टी 3 के बारे में पता होना चाहिए। यदि नया वर्कर धागा टी 4 बाद में जोड़ा गया है, तो एम को भी इसके बारे में पता होना चाहिए। यह गणना से बचा जा सकता है। क्रियान्वयन के बाद क्रिया का अनुक्रम होगा [टी 1, टी 2, टी 3] (टी 1, टी 2, टी 3 का क्रम वैसे भी हो सकता है) -> [एम]

गिनती के लिए सबसे अच्छा वास्तविक समय उदाहरण इस लिंक में दी गई जानकारी CountDownLatchExample