न्यू फेजर सिंक्रोनाइजर

फेजर बैरियर सिंक्रोनाइज़ेशन पैटर्न का एक शक्तिशाली और लचीला कार्यान्वयन है। JD. 7 में java.util.concurrent पैकेज के भाग के रूप में शामिल किया गया है।

प्रलेखन के बाद से, जैसा कि वे कहते हैं, सौ ग्राम के बिना पता नहीं लगाया जा सकता है, मैं यहां ऑपरेशन के सिद्धांत, गैर-स्पष्ट बिंदुओं का वर्णन करूंगा और उपयोग के कुछ उदाहरण दूंगा।



Phaser काफी स्वाभाविक रूप से JDK 1.5, CyclicBarrier से अपने पूर्ववर्ती की कार्यक्षमता को बढ़ाता है (आप इसके बारे में यहां पढ़ सकते हैं):वैसे, यह विस्तार इतना सामान्य है कि यह मानक लाइब्रेरी, काउंटडाउनलच से तीसरे अवरोध के अनुबंध के अनुरूप है।


निर्माता की स्थिति में शामिल हैं
  1. चरण संख्या (चरण, तुल्यकालन चक्र) | इंट चरण
  2. प्रतिभागियों की संख्या | int पार्टियों
  3. प्रतिभागियों की संख्या जिन्होंने घोषणा की / उनकी तत्परता की घोषणा नहीं की | int पहुंचे, अनियंत्रित
  4. पूर्ण अवस्था | बूलियन समाप्त हो गया
हमेशा सच:
समाप्त = गलत → चरण = [वास्तविक चरण संख्या, स्क्रैच से गिनती]% (2 31 - 1)
पार्टियों = पहुंचे + unarrived
0। अनियंत्रित, पहुंचे riv पक्ष

सभी राज्य तत्व गेटर्स से सुसज्जित हैं।


0. यदि मंच प्रबंधक एक टर्मिनल स्थिति में है (समाप्त = सत्य), तो यह परस्पर नहीं है; किसी भी नियंत्रण विधि के लिए एक कॉल तुरंत लौटता है। चरण का ऋणात्मक मान होता है, पूर्ण होने के समय पार्टियों, पहुंचे हुए, अनियंत्रित - मूल्य।


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


2. किसी भी अनियंत्रित कमी को शून्य करने के तुरंत बाद अवरोध खुल जाता है। 1, यह कि जब अंतिम प्रतिभागी को हटा दिया जाता है, तब भी, जब "खाली" चरण-प्रबंधक (नया फ़ेज़र) (या नया फ़ेज़र (0)) बनाते समय गेट बंद होते हैं।

एक तरीका या दूसरा, "आगमन" से शुरू होने वाले तरीकों में से किसी एक को कॉल करके ही बाधा को पार करना संभव है। ऐसा करने वाले धागे के संदर्भ में, onAdvance (चरण, पक्ष) संरक्षित पद्धति निष्पादित की जाती है - यदि यह सही है, तो मंच कार्यकर्ता अपने काम को समाप्त कर देता है (समाप्त) सच)। यह तंत्र आपको कक्षा के भीतर से जीवन चक्र का प्रबंधन करने की अनुमति देता है। डिफ़ॉल्ट कार्यान्वयन में, फेज़र की मृत्यु हो जाती है यदि सभी प्रतिभागियों ने बाधा छोड़ दी हो (पार्टियों = 0)

एक बाधा को खोलना एक नए चरण में एक संक्रमण है: चरण barrier चरण + 1।

यह लगभग कैसे काम करता है:
final Phaser ph = new Phaser(4); ph.arrive(); ph.register(); new Thread() {public void run(){ ph.arriveAndAwaitAdvance(); }}.start(); ph.arrive(); ph.arrive(); ph.arriveAndDeregister(); // phase number = 1 // Thread-0 released 

छवि
एक विधि राज्य के ऊपर लिखी गई है जिसके कारण यह हुआ


3. आगमनअंडरग्रिस्टर - यह सोचना हानिकारक है कि धारा पहले अपनी तत्परता की घोषणा करती है, और उसके बाद ही इसे हटा दिया जाता है, जैसा कि विधि का नाम है। सार "आगमनकर्ता" को प्रतिबिंबित करेगा, "" पार्टी कार्ड को टेबल पर रखने के लिए आया था ":-) क्या यह दृष्टिकोण समझ में अस्पष्टता को खत्म करता है (ऊपर चित्रण देखें): नए चरण पर जाने से पहले इसे तर्क पार्टियों (4) या 5 के साथ onAdance () कहा जाता है?


4. ऑनएडवांस विधि में पूर्णता तर्क को बदलने का एक उदाहरण। एक "अनजाने" स्टेजिंग मशीन का निर्माण निम्नानुसार किया जाता है:
 new Phaser() { protected boolean onAdvance(int phase, int parties) { return false; } }; 

आप तथाकथित प्रदर्शन भी कर सकते हैं। बाधा कार्रवाई - प्रतिभागियों के काम के परिणामों की एक रचना, आदि।

विशेष रूप से, अगले चरण में जाने पर क्या होता है:
छवि


के उपयोग


Phaser CyclicBarrier से प्राप्त करने के लिए, बस आगमन का उपयोग करें AdAwaitAdvance () विधि।

CountDownLatch का अनुकरण करना कुछ अधिक जटिल है:
 // aka countDown() phaser.arriveAndDeregister(); //  arrive()    // aka await() if (!phaser.isTerminated()) //  phaser.awaitAdvance( phaser.getPhase() ); 

WaitAdvance (getPhase ()) निर्माण सुरक्षित है (यद्यपि परमाणु नहीं), क्योंकि प्रतीक्षा चरण (int चरणनंबर) विधि तुरंत वापस आती है यदि निर्दिष्ट चरण पहले ही पास हो गया हो।


सामान्य तौर पर, एक स्टेज काउंटर होने से जीवन सरल हो जाता है और कक्षा अनुप्रयोगों की संख्या बढ़ जाती है।

एक पंक्ति में एन समान क्रियाओं का समानांतरकरण:
 import java.util.concurrent.Phaser; public class FBIEasterEgg { static int lines = 10; static String alphabet = "abcdefghijklmnopqrstuvwxyz"; static StringBuffer randomAlphabet = new StringBuffer(); public static void main(String[] args) { final Phaser phaser = new Phaser() { protected boolean onAdvance(int phase, int parties) { // John Nash mode /* print "deviations" for (int i = 0; i < alphabet.length(); i++) { System.out.printf("%d ", randomAlphabet.indexOf( alphabet.charAt(i) + "") - i); } System.out.println(); */ System.out.println(randomAlphabet); // randomAlphabet = new StringBuffer(); return phase >= lines; //loop count managing here } }; // everyone have to wait for the main thread phaser.register(); for (int i = 0; i < alphabet.length(); i++) { final char next = alphabet.charAt(i); phaser.register(); // ticket for the following thread new Thread() { public void run() { do { randomAlphabet.append(next); phaser.arriveAndAwaitAdvance(); // checkout } while ( !phaser.isTerminated() ); } }.start(); } System.out.println("Write this by hand and carry in the pocket:"); // some additional preparations may be done here // release phaser.arriveAndDeregister(); } } 


तब तक प्रतीक्षा करें जब तक कि दी गई घटनाओं की संख्या न हो जाए:
 class EventCounter { private Phaser count = new Phaser(1); public void eventOccured() { count.arrive(); } public void waitFor(int events) { count.register(); for (int i = 0; i < events; i++) { count.arriveAndAwaitAdvance(); } count.arriveAndDeregister(); } } 



कार्यान्वयन


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


संदर्भ


फेसर जावदोक
JDK 7 डाउनलोड पेज
कंसीडर जेएसआर -166 इंटरेस्ट साइट - JDK 6 के लिए नया java.util.concurrent डाउनलोड करने के लिए एक लिंक है।


पी। एस। नाम "निर्माता" है, निश्चित रूप से, अनाड़ी, अगर कोई जानता है / बेहतर सोचता है - छिपाना मत।
1 - बशर्ते कि फेजर पदानुक्रम की जड़ है। इस समीक्षा में, स्केलिंग तंत्र पर विचार नहीं किया गया है (मैं वैसे भी झूठ बोला होगा), javadoc देखें।

Source: https://habr.com/ru/post/In117185/


All Articles