क्या कोई सरल शब्दों में समझा सकता है कि विघटनकारी पैटर्न क्या है?


33

मैं चाहूंगा कि अगर आप मुझे एक सरल तरीके से समझा सकते हैं कि विघटनकारी संरक्षक कैसे काम करता है। इस अवधारणा को मुझे पता है के रूप में मायावी है।

शायद आपकी मदद से मैं इसे समझ सका।


जवाबों:


33

फाउलर अनुच्छेद प्रदाताओं एक अच्छा प्राइमर, और इस स्पष्टीकरण:

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

प्रत्येक निर्माता और उपभोक्ता के पास यह बताने के लिए कि यह वर्तमान में किस बफर में काम कर रहा है, एक अनुक्रम काउंटर है। प्रत्येक निर्माता / उपभोक्ता अपना स्वयं का अनुक्रम काउंटर लिखता है लेकिन दूसरों के अनुक्रम काउंटर को पढ़ सकता है। इस तरह निर्माता उपभोक्ताओं के काउंटर को यह सुनिश्चित करने के लिए पढ़ सकता है कि वह जिस स्लॉट में लिखना चाहता है वह काउंटरों पर बिना किसी ताले के उपलब्ध है। इसी प्रकार एक उपभोक्ता यह सुनिश्चित कर सकता है कि काउंटरों को देखकर एक बार दूसरे उपभोक्ता के साथ संदेश भेजने की प्रक्रिया हो।

यहाँ छवि विवरण दर्ज करें

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


9

कोरलक्यू के बारे में इस लेख से :

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

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

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

package com.coralblocks.coralqueue.sample.queue;

import com.coralblocks.coralqueue.AtomicQueue;
import com.coralblocks.coralqueue.Queue;
import com.coralblocks.coralqueue.util.Builder;

public class Basics {

    public static void main(String[] args) {

        final Queue<StringBuilder> queue = new AtomicQueue<StringBuilder>(1024, new Builder<StringBuilder>() {
            @Override
            public StringBuilder newInstance() {
                return new StringBuilder(1024);
            }
        });

        Thread producer = new Thread(new Runnable() {

            private final StringBuilder getStringBuilder() {
                StringBuilder sb;
                while((sb = queue.nextToDispatch()) == null) {
                    // queue can be full if the size of the queue
                    // is small and/or the consumer is too slow

                    // busy spin (you can also use a wait strategy instead)
                }
                return sb;
            }

            @Override
            public void run() {

                StringBuilder sb;

                while(true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to send a message to
                    // the other thread you can just do:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hello!");
                    queue.flush();

                    // you can also send in batches to increase throughput:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi!");

                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi again!");

                    queue.flush(); // dispatch the two messages above...
                }
            }
        }, "Producer");

        Thread consumer = new Thread(new Runnable() {

            @Override
            public void run() {

                while (true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to check if the producer
                    // has sent a message you just do:

                    long avail;
                    while((avail = queue.availableToPoll()) == 0) {
                        // queue can be empty!
                        // busy spin (you can also use a wait strategy instead)
                    }

                    for(int i = 0; i < avail; i++) {
                        StringBuilder sb = queue.poll();
                        // (...) do whatever you want to do with the data
                        // just don't call toString() to create garbage...
                        // copy byte-by-byte instead...
                    }
                    queue.donePolling();
                }
            }
        }, "Consumer");

        consumer.start();
        producer.start();
    }
}

अस्वीकरण: मैं कोरलक्यू के डेवलपर्स में से एक हूं।


1
आपके द्वारा वर्णित सॉफ़्टवेयर के साथ अपनी संबद्धता बताना अच्छा होगा।
हिरण हंटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.