जावा कंसीडर: साइकल बैरियर बनाम काउंटडाउन लैच


160

मैं java.util.concurrent API के माध्यम से पढ़ रहा था , और पाया कि

  • CountDownLatch: एक सिंक्रनाइज़ेशन सहायता जो एक या अधिक थ्रेड्स को प्रतीक्षा करने की अनुमति देती है, जब तक कि अन्य थ्रेड्स में किए गए संचालन का एक सेट पूरा नहीं हो जाता।
  • CyclicBarrier: एक सिंक्रोनाइज़ेशन सहायता जो सभी थ्रेड्स के सेट को एक दूसरे के लिए एक सामान्य बाधा बिंदु तक पहुंचने की प्रतीक्षा करने की अनुमति देती है।

मेरे लिए दोनों समान हैं, लेकिन मुझे यकीन है कि इसके लिए बहुत कुछ है।

उदाहरण के लिए, में CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier

क्या दोनों के बीच कोई अन्य अंतर है?
वे कौन से स्थान हैं use casesजहाँ कोई उलटी गिनती के मूल्य को रीसेट करना चाहेगा?


12
घटनाओं के इंतजार में लाचियां हैं; बाधाएं अन्य धागों की प्रतीक्षा में हैं। - प्रैक्टिस में जावा कंसर्टिबिलिटी, बी.गेटेज़ एट अल।
user2418306

जवाबों:


137

एक बड़ा अंतर यह है कि साइक्लिक बैरियर एक वैकल्पिक (वैकल्पिक) रन करने योग्य कार्य करता है जो सामान्य अवरोध स्थिति पूरा होने के बाद चलाया जाता है।

यह आपको बाधा की प्रतीक्षा कर रहे ग्राहकों की संख्या और बाधा को ट्रिगर करने के लिए आवश्यक संख्या प्राप्त करने की अनुमति देता है। ट्रिगर हो जाने के बाद बैरियर को रीसेट कर दिया जाता है और फिर से इस्तेमाल किया जा सकता है।

सरल उपयोग के मामलों के लिए - सेवाएं शुरू करना आदि ... एक उलटी गिनती ठीक है। एक CyclicBarrier अधिक जटिल समन्वय कार्यों के लिए उपयोगी है। इस तरह की चीज़ का एक उदाहरण समानांतर संगणना होगा - जहाँ गणना में कई उप-प्रकार शामिल होते हैं - जैसे MapReduce


6
"यह आपको बैरियर पर प्रतीक्षा करने वाले ग्राहकों की संख्या और बाधा को ट्रिगर करने के लिए आवश्यक संख्या प्राप्त करने की अनुमति देता है। एक बार ट्रिगर बाधित होने पर रीसेट हो जाता है और इसे फिर से उपयोग किया जा सकता है।" मैं वास्तव में इस बिंदु को पसंद करता हूं। लेखों के एक जोड़े को मैंने पढ़ा है कि साइक्लिक बैरियर चक्रीय है क्योंकि आप रीसेट () विधि को लागू करते हैं। यह सच है, लेकिन वे जो अक्सर उल्लेख नहीं करते हैं वह यह है कि बाधा को ट्रिगर होते ही स्वचालित रूप से रीसेट कर दिया जाता है। मैं इसे दर्शाने के लिए कुछ नमूना कोड पोस्ट करूंगा।
केविन ली

@ केविन ली के लिए धन्यवाद "बाधा शुरू होते ही स्वचालित रूप से रीसेट हो जाता है।" इसलिए कोड में रीसेट () को कॉल करने की आवश्यकता नहीं है।
सुपरनोवा

134

एक और अंतर है।

ए का उपयोग करते समय CyclicBarrier, धारणा यह है कि आप बैरियर को ट्रिगर करने वाले प्रतीक्षा थ्रेड्स की संख्या निर्दिष्ट करते हैं। यदि आप 5 निर्दिष्ट करते हैं, तो आपके पास कॉल करने के लिए कम से कम 5 धागे होने चाहिए await()

ए का उपयोग करते समय CountDownLatch, आप कॉल की संख्या को निर्दिष्ट करते हैं countDown()जिसके परिणामस्वरूप सभी प्रतीक्षा धागे जारी किए जाएंगे। इसका मतलब है कि आप CountDownLatchकेवल एक ही धागे के साथ उपयोग कर सकते हैं ।

"आप ऐसा क्यों करेंगे?", आप कह सकते हैं। कल्पना करें कि आप किसी अन्य व्यक्ति द्वारा कोडबैक करने वाले रहस्यमय एपीआई का उपयोग कर रहे हैं। आप चाहते हैं कि आपका एक सूत्र प्रतीक्षा करे जब तक कि एक निश्चित कॉलबैक को कई बार कॉल न किया जाए। आपके पास कोई विचार नहीं है जो कॉलबैक को थ्रेड करता है। इस मामले में, एक CountDownLatchसही है, जबकि मैं इसे CyclicBarrier(वास्तव में, मैं कर सकता हूं) का उपयोग करके इसे लागू करने के किसी भी तरीके के बारे में नहीं सोच सकता हूं, लेकिन इसमें टाइमआउट शामिल है ... yuck!)।

मैं बस इच्छा है कि CountDownLatchरीसेट किया जा सकता है!


10
मुझे लगता है कि यह वह उत्तर है जो बेहतर रूप से सैद्धांतिक अंतर दिखाता है। तथ्य यह है कि latches को कई बार एक विधि कहकर तोड़ा जा सकता है जबकि बाधाओं को प्रतीक्षा करने के लिए थ्रेड्स का एक सटीक अमाउंट चाहिए ()।
flagg19

43
सही - वह प्रमुख अंतर है: काउंटडाउनचैच -> नंबरऑफ कॉल, साइक्लिक बैरियर -> नंबरऑफट्रेड्स
इवान

1
मैं मानता हूं कि यह CountDownLatchपुन: प्रयोज्य होने के लिए बहुत अच्छा होगा - एक सुरक्षित प्रतीक्षा-अधिसूचित को लागू करने के लिए मैं एक वर्कअराउंड का उपयोग करता हूं CountDownLatch, संरक्षित कोड ब्लॉक दर्ज किए जाने पर (जब कुंडी शून्य तक पहुंच जाती है) तुरंत एक नया काम करना है । यह सभी परिस्थितियों / पाठ्यक्रम के दायरे में लागू नहीं है, लेकिन मुझे लगा कि यह ध्यान देने योग्य है कि यह गोल्डीलॉक्स स्थितियों में एक विकल्प है।
पंचांग

2
इस विषय पर सबसे अच्छे उत्तरों में से एक। Java Concurrency in Practice- एक ही बात कहते हैं Latches are for waiting for events; barriers are for waiting for other threads.:। इन दोनों के बीच अंतर को समझने के लिए एक प्राथमिक और आवश्यक बिंदु।
राहुल देव मिश्रा

जावा 8 डॉक का कहना है कि "एन काउंटडाउनलचैट एन के लिए इनिशियलाइज़्ड का उपयोग एक थ्रेड प्रतीक्षा करने के लिए किया जा सकता है जब तक कि एन थ्रेड्स ने कुछ कार्रवाई पूरी नहीं की है, या कुछ एक्शन एन बार पूरा हो चुका है।" मुझे लगता है: CountDownLatch -> NumberOfCalls या CountDownLatch -> NumberOfThreads
nir

41

एक बिंदु जिसका किसी ने अभी तक उल्लेख नहीं किया है, वह यह है कि, CyclicBarrierयदि किसी थ्रेड में कोई समस्या है (समयबाह्य, बाधित ...), तो अन्य सभी जो await()एक अपवाद हैं, को अपवाद मिल गया है। जावदोक देखें:

CyclicBarrier विफल सिंक्रनाइज़ेशन प्रयासों के लिए एक ऑल-ऑर-नो-ब्रेकेज मॉडल का उपयोग करता है: यदि कोई रुकावट, विफलता या टाइमआउट के कारण समय से पहले एक अवरोध बिंदु को छोड़ देता है, तो उस अवरोध बिंदु पर प्रतीक्षा करने वाले अन्य सभी थ्रेड्स BrokenBarrierException (या InterruptedException) के माध्यम से आमतौर पर छोड़ देंगे। यदि वे भी लगभग उसी समय बाधित होते थे)।


22

मुझे लगता है कि JavaDoc ने अंतरों को स्पष्ट रूप से समझाया है। अधिकांश लोग जानते हैं कि काउंटडाउनचैट को रीसेट नहीं किया जा सकता है, हालांकि, साइक्लिक बैरियर कर सकते हैं। लेकिन यह एकमात्र अंतर नहीं है, या साइक्लिक बैरियर का नाम बदलकर ResetbleCountDownLatch रखा जा सकता है। हमें उनके लक्ष्यों के परिप्रेक्ष्य से अंतर बताना चाहिए, जो कि जावाडॉक में वर्णित हैं

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

CyclicBarrier: एक सिंक्रनाइज़ेशन सहायता जो सभी थ्रेड्स के सेट को एक दूसरे के लिए एक सामान्य बाधा बिंदु तक पहुंचने की प्रतीक्षा करने की अनुमति देती है।

काउंटडाउनलच में, एक या एक से अधिक थ्रेड्स हैं, जो अन्य थ्रेड्स के पूरा होने के लिए इंतजार कर रहे हैं । इस स्थिति में, दो प्रकार के धागे हैं, एक प्रकार प्रतीक्षा कर रहा है, दूसरा प्रकार कुछ कर रहा है, अपने कार्यों को पूरा करने के बाद, वे प्रतीक्षा कर सकते हैं या बस समाप्त हो सकते हैं।

साइक्लिक बैरियर में, केवल एक प्रकार के धागे हैं, वे एक-दूसरे के लिए इंतजार कर रहे हैं, वे बराबर हैं।


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

मैं मानता हूं कि CountDownLatch को स्वाभाविक रूप से दो भूमिकाओं की आवश्यकता होती है: काउंटडाउन के लिए एक क्लाइंट और प्रतीक्षा के लिए एक क्लाइंट। दूसरी ओर, CyclicBarrier ग्राहक प्रतीक्षा पद्धति के साथ ठीक काम कर सकते हैं।
isaolmez

14

काउंटडाउनचैच के लिए जावदोस्क में मुख्य अंतर सही प्रलेखित है। अर्थात्:

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

स्रोत 1.6 Javadoc


4
यदि उनका अंतर बस रीसेट किया जा सकता है या नहीं, तो CyclicBarrier को ResetableCountDownLatch नाम दिया जा सकता है, जो अंतर के कारण अधिक सार्थक है।
जेम्स.एक्सयू

12

एक-बार सिंक्रोनाइज़ेशन के लिए एक काउंटडाउनचैट का उपयोग किया जाता है। CountDownLatch का उपयोग करते समय, किसी भी थ्रेड को काउंटडाउन () को जितनी बार चाहें कॉल करने की अनुमति दी जाती है। थ्रेड्स जिसे वेट कहा जाता है () अन्य अनब्लॉक थ्रेड्स द्वारा काउंटडाउन () को कॉल करने के कारण गिनती शून्य तक पहुंचने तक अवरुद्ध है। CountDownLatch के लिए जावाडोक कहता है:

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

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

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

बैरियर को चक्रीय कहा जाता है क्योंकि प्रतीक्षा थ्रेड्स जारी होने के बाद इसका फिर से उपयोग किया जा सकता है।

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


12

इस प्रश्न का पर्याप्त रूप से पहले से ही उत्तर दिया गया है, लेकिन मुझे लगता है कि मैं कुछ कोड पोस्ट करके थोड़ा-बहुत मूल्य जोड़ सकता हूं।

चक्रीय अवरोध के व्यवहार को स्पष्ट करने के लिए, मैंने कुछ नमूना कोड बनाए हैं। जैसे ही बैरियर को इत्तला दी जाती है, यह स्वचालित रूप से रीसेट हो जाता है ताकि इसे फिर से इस्तेमाल किया जा सके (इसलिए यह "चक्रीय" है)। जब आप प्रोग्राम चलाते हैं, तो देखें कि प्रिंट आउट "लेट्स प्ले" केवल ट्रिगर के बाधित होने के बाद चालू हो जाता है।

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierCycles {

    static CyclicBarrier barrier;

    public static void main(String[] args) throws InterruptedException {
        barrier = new CyclicBarrier(3); 

        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);

        System.out.println("Barrier automatically resets.");

        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
    }

}


class Worker extends Thread {
    @Override
    public void run() {
        try {
            CyclicBarrierCycles.barrier.await();
            System.out.println("Let's play.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

8

जब मैं Latches और cyclicbarriers के बारे में अध्ययन कर रहा था तो मैं इस रूपकों के साथ आया। साइक्लिसबैरियर : कल्पना कीजिए कि एक कंपनी का एक बैठक कक्ष है। बैठक शुरू करने के लिए, एक निश्चित संख्या में बैठक में उपस्थित लोगों को बैठक में आना होता है (इसे आधिकारिक बनाने के लिए)। निम्नलिखित एक सामान्य बैठक सहभागी का कोड है (एक कर्मचारी)

class MeetingAtendee implements Runnable {

CyclicBarrier myMeetingQuorumBarrier;

public MeetingAtendee(CyclicBarrier myMileStoneBarrier) {
    this.myMeetingQuorumBarrier = myMileStoneBarrier;
}

@Override
public void run() {
    try {
        System.out.println(Thread.currentThread().getName() + " i joined the meeting ...");
        myMeetingQuorumBarrier.await();
        System.out.println(Thread.currentThread().getName()+" finally meeting stared ...");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (BrokenBarrierException e) {
        System.out.println("Meeting canceled! every body dance <by chic band!>");
    }
 }
}

कर्मचारी बैठक में शामिल होता है, बैठक शुरू करने के लिए दूसरों का इंतजार करता है। वह भी बाहर निकलता है अगर बैठक रद्द हो जाती है :) तो हमारे पास यह है कि कैसे खुराक दूसरों को दिखाने के लिए इंतजार करना पसंद नहीं करता है और यदि वह अपने रोगी को खो देता है, तो वह बैठक रद्द कर देता है।

class MeetingAtendeeTheBoss implements Runnable {

CyclicBarrier myMeetingQuorumBarrier;

public MeetingAtendeeTheBoss(CyclicBarrier myMileStoneBarrier) {
    this.myMeetingQuorumBarrier = myMileStoneBarrier;
}

@Override
public void run() {
    try {
        System.out.println(Thread.currentThread().getName() + "I am THE BOSS - i joined the meeting ...");
        //boss dose not like to wait too much!! he/she waits for 2 seconds and we END the meeting
        myMeetingQuorumBarrier.await(1,TimeUnit.SECONDS);
        System.out.println(Thread.currentThread().getName()+" finally meeting stared ...");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (BrokenBarrierException e) {
        System.out.println("what WHO canceled The meeting");
    } catch (TimeoutException e) {
        System.out.println("These employees waste my time!!");
    }
 }
}

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

CyclicBarrier meetingAtendeeQuorum = new CyclicBarrier(5);
Thread atendeeThread = new Thread(new MeetingAtendee(meetingAtendeeQuorum));
Thread atendeeThreadBoss = new Thread(new MeetingAtendeeTheBoss(meetingAtendeeQuorum));
    atendeeThread.start();
    atendeeThreadBoss.start();

आउटपुट:

//Thread-1I am THE BOSS - i joined the meeting ...
// Thread-0 i joined the meeting ...
// These employees waste my time!!
// Meeting canceled! every body dance <by chic band!>

एक और परिदृश्य है जिसमें एक और बाहरी धागा (एक भूकंप) मीटिंग को रद्द कर देता है (कॉल रीसेट विधि)। इस स्थिति में सभी प्रतीक्षा सूत्र अपवाद द्वारा जागृत हो जाते हैं।

class NaturalDisasters implements Runnable {

CyclicBarrier someStupidMeetingAtendeeQuorum;

public NaturalDisasters(CyclicBarrier someStupidMeetingAtendeeQuorum) {
    this.someStupidMeetingAtendeeQuorum = someStupidMeetingAtendeeQuorum;
}

void earthQuakeHappening(){
    System.out.println("earth quaking.....");
    someStupidMeetingAtendeeQuorum.reset();
}

@Override
public void run() {
    earthQuakeHappening();
 }
}

रनिंग कोड के परिणामस्वरूप मजेदार आउटपुट मिलेगा:

// Thread-1I am THE BOSS - i joined the meeting ...
// Thread-0 i joined the meeting ...
// earth quaking.....
// what WHO canceled The meeting
// Meeting canceled! every body dance <by chic band!>

आप बैठक कक्ष में एक सचिव को भी जोड़ सकते हैं, यदि कोई बैठक आयोजित की जाती है तो वह हर बात का दस्तावेजीकरण करेगा लेकिन वह बैठक का हिस्सा नहीं है:

class MeetingSecretary implements Runnable {

@Override
public void run() {
        System.out.println("preparing meeting documents");
        System.out.println("taking notes ...");
 }
}

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

public class Visitor implements Runnable{

CountDownLatch exhibitonDoorlatch = null;

public Visitor (CountDownLatch latch) {
    exhibitonDoorlatch  = latch;
}

public void run() {
    try {
        exhibitonDoorlatch .await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println("customer visiting exebition");
 }
}

और कार्यकर्ता कैसे प्रदर्शनी की तैयारी कर रहे हैं:

class Worker implements Runnable {

CountDownLatch myTodoItem = null;

public Worker(CountDownLatch latch) {
    this.myTodoItem = latch;
}

public void run() {
        System.out.println("doing my part of job ...");
        System.out.println("My work is done! remove it from todo list");
        myTodoItem.countDown();
 }
}

    CountDownLatch preperationTodoList = new CountDownLatch(3);

    // exhibition preparation workers  
    Worker      electricalWorker      = new Worker(preperationTodoList);
    Worker      paintingWorker      = new Worker(preperationTodoList);

    // Exhibition Visitors 
    ExhibitionVisitor exhibitionVisitorA = new ExhibitionVisitor(preperationTodoList);
    ExhibitionVisitor exhibitionVisitorB = new ExhibitionVisitor(preperationTodoList);
    ExhibitionVisitor exhibitionVisitorC = new ExhibitionVisitor(preperationTodoList);

    new Thread(electricalWorker).start();
    new Thread(paintingWorker).start();

    new Thread(exhibitionVisitorA).start();
    new Thread(exhibitionVisitorB).start();
    new Thread(exhibitionVisitorC).start();

7

संक्षेप में , बस दोनों के बीच महत्वपूर्ण कार्यात्मक अंतर को समझने के लिए :

public class CountDownLatch {
    private Object mutex = new Object();
    private int count;

    public CountDownLatch(int count) {
        this.count = count;
    }

    public void await() throws InterruptedException {
        synchronized (mutex) {
            while (count > 0) {
                mutex.wait();
            }
        }
    }

    public void countDown() {
        synchronized (mutex) {
            if (--count == 0)
                mutex.notifyAll();
        }

    }
}

तथा

public class CyclicBarrier {
    private Object mutex = new Object();
    private int count;

    public CyclicBarrier(int count) {
        this.count = count;
    }

    public void await() throws InterruptedException {
        synchronized (mutex) {
            count--;
            while(count > 0)
                mutex.wait();
            mutex.notifyAll();
        }
    }
}

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

हालांकि, उपरोक्त वर्ग, पूरी तरह कार्यात्मक और समतुल्य हैं, प्रदान की गई कार्यक्षमता के भीतर, उनके संवाददाता नामों के लिए।

एक अलग नोट पर, CountDownLatchभीतरी वर्ग के उपवर्गों का उपयोग AQSकरते समय, (मेरा संदेह यह है कि यह किसी अन्य तरीके से हो सकता है या दोनों AQS का उपयोग कर सकते हैं या दोनों लॉक का उपयोग कर सकते हैं - प्रदर्शन दक्षता के किसी भी नुकसान के बिना)CyclicBarrierReentrantLock


5

एक स्पष्ट अंतर है, केवल एन थ्रेड्स एक चक्र में रिलीज होने के लिए एन के चक्रीय बैरियर पर इंतजार कर सकते हैं। लेकिन असीमित संख्या में थ्रेड्स एन के काउंटडाउन लॉच पर इंतजार कर सकते हैं। काउंट डाउन डीक्रीमेंट एक थ्रेड एन बार या एन थ्रेड्स एक बार या कॉम्बिनेशन द्वारा किया जा सकता है।


4

CyclicBarrier के मामले में, जैसे ही सभी बच्चे थ्रेड्स में बाधा डालना शुरू करते हैं। बैटरी (), Runnable को बैरियर में निष्पादित किया जाता है। प्रत्येक बच्चे के धागे में अवरोध.वाइट को समाप्त करने के लिए अलग-अलग समय लगेगा, और वे सभी एक ही समय में समाप्त होते हैं।


4

में CountDownLatch , अन्य थ्रेड के लिए मुख्य सूत्र प्रतीक्षा करता है उनके निष्पादन पूरा करने के लिए। में CyclicBarrier , कार्यकर्ता धागे उनके निष्पादन पूरा करने के लिए एक दूसरे के लिए प्रतीक्षा करें।

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


यह मुख्य धागा नहीं होना चाहिए। यह कोई भी धागा हो सकता है जो काउंटडाउनचैट बनाता है और इसे अन्य गैर-मुख्य थ्रेड्स के साथ साझा करता है।
अनिकेत ठाकुर

1

काउंटडाउनचैट किसी भी चीज़ की गिनती है; साइक्लिक बैरियर केवल थ्रेड के लिए एक गणना है

मान लें कि 5 श्रमिक धागे और एक शिपर धागा हैं, और जब श्रमिक 100 वस्तुओं का उत्पादन करते हैं, तो शिपर उन्हें बाहर भेज देंगे।

CountDownLatch के लिए, काउंटर श्रमिकों या वस्तुओं पर हो सकता है

CyclicBarrier के लिए, काउंटर केवल श्रमिकों पर हो सकता है

यदि एक कर्मचारी अनंत नींद में गिर जाता है, तो आइटम पर काउंटडाउनचैच के साथ, शिप जहाज कर सकते हैं; हालांकि, साइक्लिक बैरियर के साथ, शिपर को कभी नहीं बुलाया जा सकता है


0

@ केविन ली और @ जोंन ने मैं चक्रीय बैरियर को वैकल्पिक रननेबल के साथ आज़माया। ऐसा लगता है कि यह शुरुआत में चलता है और चक्रीय बैरियर के बाद इत्तला दे दी जाती है। यहाँ कोड और आउटपुट है

स्टेटिक साइक्लिक बैरियर बैरियर;

    public static void main(String[] args) throws InterruptedException {
        barrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                System.out.println("I run in the beginning and after the CyclicBarrier is tipped");
            }
        });

        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);

        System.out.println("Barrier automatically resets.");

        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
        Thread.sleep(1000);
        new Worker().start();
    }

उत्पादन

I run in the beginning and after the CyclicBarrier is tipped
Let's play.
Let's play.
Let's play.
Barrier automatically resets.
I run in the beginning and after the CyclicBarrier is tipped
Let's play.
Let's play.
Let's play.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.