2016-03-20 6 views
5

तो, मैं जावा 8. मैं एक धारा है कि एक अलग थ्रेड (सिर्फ शैक्षिक उद्देश्यों के लिए) पर चला सकते हैंStream.parallel() एक नया धागा का उपयोग करता है?

String oracle = "http://www.oracle.com"; 
URL url = new URL(oracle); 
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); 
in.lines().parallel().forEach(System.out::println); 
System.out.print("CLOSING THE INPUT STREAM!, shouldnt this crash?"); 
in.close(); 

बनाने के लिए कोशिश कर रहा हूँ में शुरू की गई स्ट्रीम एपीआई के आसपास मेरे सिर प्राप्त करने के लिए कोशिश कर रहा हूँ नतीजा यह नहीं है कि मैं क्या उम्मीद करूंगा .. (मैं एक दुर्घटना की उम्मीद कर रहा था, क्योंकि मैंने इनपुट स्ट्रीम बंद कर दिया था जबकि अन्य धागा इसे पढ़ रहा था)। .parallel() विधि कॉल पर ध्यान दें। इसके बजाए कोड किसी अनुक्रमिक तरीके से निष्पादित नहीं होता है, जिसमें कोई समस्या नहीं है।

उत्पादन:

<script language="JavaScript" src="http://www.oracleimg.com/us/assets/metrics/ora_ocom_hp.js"></script> 
<!-- End SiteCatalyst code --> 

      <!-- SS_END_SNIPPET(fragment6,1)--> 
<!-- SS_BEGIN_SNIPPET(fragment7,ui)-->   <!-- SS_END_SNIPPET(fragment7,ui)--> 
</html> 
CLOSING THE INPUT STREAM!, shouldnt this crash? 

किसी को भी पता है क्या हो रहा है? मेरा कोड क्यों नहीं क्रैश हो रहा है?

+2

यदि आप चीजों को अवरुद्ध नहीं करना चाहते हैं तो आप 'फोर्कजोइनपूल' का उपयोग कर सकते हैं। – Maroun

उत्तर

12

समानांतर धारा वास्तव में एकाधिक धागे के लिए लाइनों को पढ़ने के काम को विभाजित करने का प्रयास करेगी। लेकिन आमंत्रण स्वयं अवरुद्ध हो रहा है, यानी कथन तब तक प्रतीक्षा करता है जब तक कि सभी धागे अगले कथन (जहां आप इनपुट स्ट्रीम बंद करते हैं) पर आगे बढ़ने के लिए समाप्त हो जाते हैं। नोट करने के लिए

एक बात है कि forEach गारंटी नहीं देता कि समानांतर कार्यों धारा तत्वों की एक ही क्रम में निष्पादित, इसलिए इस मामले में मुद्रित लाइनों मूल वेब पेज के साथ एक ही क्रम में नहीं हो सकता है (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#forEach-java.util.function.Consumer- देखना है)।

+0

मैं समझता हूं, अच्छा जवाब, यदि आप वर्तमान एक निष्क्रिय को छोड़ने जा रहे हैं तो नया धागा बनाने का क्या मतलब है? .parallel() doenst सभी उपयोगी लगता है। मुझे लगता है कि यह एक अलग सवाल है। जैसे ही मैं कर सकता हूं, आपके प्रश्न को स्वीकार कर लिया जाएगा। धन्यवाद – feresr

+2

@feresr: बिंदु यह है कि, यदि यह समानांतर में काम करने के लिए दस धागे (कहता है) उत्पन्न करता है, तो पूरा ऑपरेशन केवल एक में किए जाने से दस गुना तेज हो सकता है। (व्यवहार में यह तेजी से नहीं जा सकता है - या कैशिंग प्रभावों के कारण भी तेज़ हो सकता है - लेकिन यह विचार है, वैसे भी!) – psmears

+2

समांतर धाराओं के साथ, निष्पादन तेज हो सकता है। आप एक अनुक्रमिक धारा के खिलाफ अंतर को मापने का प्रयास कर सकते हैं। इसे अभी भी अवरुद्ध करने की आवश्यकता है क्योंकि 'forEach' एक _terminal ऑपरेशन_ है जिसे एक निश्चित परिणाम को गठबंधन करने की आवश्यकता है। आप एक 'योग' ऑपरेशन भी कॉल कर सकते हैं जिस स्थिति में इसे परिणाम के संयुक्त होने की प्रतीक्षा करनी चाहिए। – manouti

2

यदि आप पृष्ठभूमि में चीजों को तुरंत पूरा करने के बिना अवरुद्ध करना चाहते हैं तो आप java.util.concurrent.CompletableFuture.runAsync(Runnable) और संबंधित विधियों का उपयोग कर सकते हैं। यह एक CompletableFuture देता है जिसे आवश्यक होने पर बाद में जोड़ा जा सकता है।

1

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

हालांकि एक विशेष मामला है: यदि समानांतर स्ट्रीम ऑपरेशन अपवाद फेंकता है, तो मुख्य थ्रेड में आपकी स्ट्रीम प्रसंस्करण समाप्त होती है (असाधारण रूप से), लेकिन अन्य पृष्ठभूमि धागे अभी भी कुछ इनपुट हिस्सों को संसाधित करना जारी रख सकते हैं। आप इस जाँच निम्नलिखित कोड का उपयोग कर सकते हैं:

// Create list of Strings "0", "1", "2", ..., "99" 
List<String> list = IntStream.range(0, 100).mapToObj(String::valueOf) 
          .collect(Collectors.toCollection(ArrayList::new)); 
// replace one with non-numeric 
list.set(1, "foo"); 

// Convert every string to number and print it 
try { 
    list.parallelStream().mapToInt(Integer::parseInt).forEach(System.out::println); 
} catch (NumberFormatException e) { 
    // well some non-number encountered 
} 
System.out.println("Exited"); 

इस कोड को आप कभी कभी देख सकते हैं कि कुछ संख्या "Exited" संदेश के बाद मुद्रित कर रहे हैं चल रहा है।

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