2015-03-11 9 views
11

में नहीं चलती है मेरे पास तत्वों का संग्रह है जो मैं समानांतर में संसाधित करना चाहता हूं। जब मैं List का उपयोग करता हूं, समांतरता कार्य करता है। हालांकि, जब मैं Set का उपयोग करता हूं, तो यह समानांतर में नहीं चलता है।हैशसेट से समांतर स्ट्रीम समानांतर

public static void main(String[] args) { 
    ParallelTest test = new ParallelTest(); 

    List<Integer> list = Arrays.asList(1,2); 
    Set<Integer> set = new HashSet<>(list); 

    ForkJoinPool forkJoinPool = new ForkJoinPool(4); 

    System.out.println("set print"); 
    try { 
     forkJoinPool.submit(() -> 
      set.parallelStream().forEach(test::print) 
     ).get(); 
    } catch (Exception e) { 
     return; 
    } 

    System.out.println("\n\nlist print"); 
    try { 
     forkJoinPool.submit(() -> 
      list.parallelStream().forEach(test::print) 
     ).get(); 
    } catch (Exception e) { 
     return; 
    } 
} 

private void print(int i){ 
    System.out.println("start: " + i); 
    try { 
     TimeUnit.SECONDS.sleep(1); 
    } catch (InterruptedException e) { 
    } 
    System.out.println("end: " + i); 
} 

यह आउटपुट है कि मैं खिड़कियों 7

set print 
start: 1 
end: 1 
start: 2 
end: 2 

list print 
start: 2 
start: 1 
end: 1 
end: 2 

पर मिलता है हम देख सकते हैं कि Set से पहले तत्व करना पड़ा है:

मैं एक कोड नमूना है कि समस्या से पता चलता लिखा था दूसरे तत्व संसाधित होने से पहले खत्म करें। List के लिए, दूसरा तत्व पहले तत्व समाप्त होने से पहले शुरू होता है।

क्या आप मुझे बता सकते हैं कि इस समस्या का कारण क्या है, और Set संग्रह का उपयोग करके इसे कैसे टालना है?

+0

इसे दो से अधिक तत्वों के साथ आज़माएं, जैसे 10. तत्व या कुछ।2 के साथ परिणाम बहुत अस्पष्ट हैं – nafas

+0

जब आप 10 के साथ प्रयास करते हैं तो भी आप सभी सेट तत्वों को समानांतर नहीं कर सकते हैं। और मुझे समांतर में सभी तत्वों को चलाने की आवश्यकता है। – Nemo

+0

किसी भी तरह से इस 10 के लिए उत्पादन (10 निष्पादकों के पूल के साथ) है तत्वों सेट प्रिंट शुरू: 8 शुरू: 0 शुरू: 4 शुरू: 6 शुरू: 2 अंत: 2 अंत: 6 अंत: 4 अंत: 0 शुरू: 1 अंत: 8 शुरू: 9 शुरू: 5 शुरू: 7 शुरू: 3 अंत: 3 अंत: 5 अंत: 9 अंत: 7 अंत: 1 ,210 सूची प्रिंट शुरू : 7 शुरू: 3 शुरू: 0 शुरू: 6 शुरू: 9 शुरू: 8 शुरू: 5 शुरू: 4 शुरू: 2 शुरू: 1 अंत: 0 अंत: 6 अंत: 7 अंत: 9 अंत: 2 अंत: 3 अंत: 8 अंत: 5 अंत: 1 अंत: 4 नहीं सभी सेट तत्वों से [यहां] (http आ रहा है समानांतर – Nemo

उत्तर

20

मैं आपके द्वारा देखे जाने वाले व्यवहार को पुन: उत्पन्न कर सकता हूं, जहां समांतरता आपके द्वारा निर्दिष्ट फोर्क-जॉइन पूल समांतरता के समांतरता से मेल नहीं खाती है। फोर्क-इन पूल पूल समांतरता को 10 तक सेट करने के बाद, और संग्रह में तत्वों की संख्या में 50 की वृद्धि करने के बाद, मुझे सूची-आधारित धारा की समांतरता केवल 6 तक बढ़ रही है, जबकि सेट-आधारित स्ट्रीम की समांतरता कभी ऊपर नहीं जाती है 2.

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

java.util.stream.AbstractTask कक्षा में, LEAF_TARGET फ़ील्ड निर्धारित विभाजन की मात्रा निर्धारित करता है, जो बदले में समांतरता की मात्रा निर्धारित करता है। इस क्षेत्र का मूल्य ForkJoinPool.getCommonPoolParallelism() पर आधारित है जो निश्चित रूप से सामान्य पूल के समांतरता का उपयोग करता है, न कि जो भी पूल कार्य चलाने के लिए होता है।

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

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

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "10"); 

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

आप इस संपत्ति को -D विकल्प का उपयोग कर कमांड लाइन पर भी सेट कर सकते हैं।

फिर से, यह गारंटीकृत व्यवहार नहीं है, और यह भविष्य में बदल सकता है। लेकिन यह तकनीक संभवतः भविष्य के लिए जेडीके 8 कार्यान्वयन के लिए काम करेगी।

+0

में चलाएँ: //stackoverflow.com/questions/36947336/why-does-the-parallel-strea m-not-use-all-the-threads-of-the-forkjoinpool? noredirect = 1), _Arguably के बारे में सवाल यह एक बग_ है: क्या वर्तमान 'फोर्कजॉइनपूल' (डिफ़ॉल्ट या अन्यथा) के समांतरता का उपयोग करना होगा। या कुछ और? –

+0

नहीं, एक बग नहीं। इस प्रकार 'फोर्कजोइनपूल' काम करता है - इसमें अनावश्यक थ्रेड प्रसार के खिलाफ बैक-प्रेशर तंत्र की तरह कुछ है। मैंने आपके द्वारा लिंक किए गए प्रश्न का उत्तर जोड़ा है, उस व्यवहार को समझाते हुए। –

+1

@SotiriosDelimanolis यहां भी Dimitar की टिप्पणी देखें। मैं देखता हूं कि आप लोग [अन्य प्रश्न] पर भी इस पर चर्चा करते हैं (http://stackoverflow.com/questions/36947336/why-does-the-parallel-stream-not-use-all-the-threads-of-the- फोर्कजोइनपूल) –

संबंधित मुद्दे