2011-09-26 9 views
10

मुझे अभी पता चला है कि सिर्फ एनआईओ सुविधा है, जावा एनआईओ पाइप जो थ्रेड के बीच डेटा पास करने के लिए डिज़ाइन की गई है। क्या एक कतार पर गुजरने वाले अधिक पारंपरिक संदेश पर इस तंत्र का उपयोग करने का कोई फायदा है, जैसे कि ArrayBlockingQueue?जावा एनआईओ पाइप बनाम ब्लॉकिंगक्यूयू

+0

पाइप्स कर्नेल के माध्यम से जाते हैं, चयनकर्ता के पास शायद ही कभी उपयोगी होता है ... जिसे लिनक्स पर पाइप के माध्यम से कार्यान्वित किया जाता है ... – bestsss

+0

@bestsss विस्तृत करने के लिए देखभाल करता है? आप नोटिफिकेशन प्राप्त करने के लिए चयनकर्ताओं के साथ पाइप पंजीकृत कर सकते हैं, समस्या क्या है? – raffian

+0

@ ड्रैफ़ियन, इसे आसानी से रखने के लिए - आप वास्तव में आईपीसी के लिए पाइप्स का उपयोग नहीं कर सकते हैं और प्रक्रिया के भीतर जानकारी पास करने के लिए बहुत अधिक प्रभावी तरीका हैं। – bestsss

उत्तर

6

आम तौर पर किसी अन्य थ्रेड के लिए डेटा पास करने का सबसे आसान तरीका एक निष्पादक सेवा का उपयोग करना है। यह एक कतार और धागा पूल दोनों को लपेटता है (0 धागा हो सकता है)

जब आप एक पुस्तकालय है जो एनआईओ चैनल का समर्थन करता है तो आप पाइप का उपयोग कर सकते हैं। यह भी उपयोगी है अगर आप धागे के बीच डेटा के बाइटबफर पास करना चाहते हैं।

अन्यथा यह आमतौर पर एक ArrayBlockingQueue का उपयोग करने के लिए सरल/तेज़ है।

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

The Exchanger and GC-less Java

+0

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

+0

एक पाइप एक निश्चित आकार है। समस्या तब भी वही है जब निर्माता तेजी से उत्पादन कर रहा है, इसे रोकना है। यदि उपभोक्ता खत्म होने से पहले निर्माता कभी बफर भर नहीं रहा है तो इसे रोकने के लिए नहीं है (किसी भी मामले में) –

+1

पाइप्स का चयन Selector.wakeup को लागू करने के लिए किया जाता है, इससे परे कि वे बहुत उपयोगी नहीं हैं, क्योंकि स्मृति केवल समाधान अधिक प्रभावी होते हैं और कर्नेल के माध्यम से मत जाओ। – bestsss

1

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

आम तौर पर पाइप उपभोक्ता-उत्पादक समस्या का प्रतिनिधित्व करते हैं और इस तरह से लागू होने की संभावना है ताकि दोनों धागे सहयोग कर सकें और बाहरी रूप से छूट नहीं दी जा सके।

2

मुझे विश्वास है कि एक एनआईओ पाइप डिज़ाइन किया गया था ताकि आप चयनकर्ता लूप के अंदर एक चैनल को डेटा को थ्रेड से सुरक्षित तरीके से भेज सकें, दूसरे शब्दों में, कोई धागा पाइप को लिख सकता है और डेटा दूसरे में संभाला जाएगा चयनकर्ता पाश के अंदर, पाइप के चरम। जब आप एक पाइप को लिखते हैं तो आप चैनल को दूसरी तरफ पठनीय बनाते हैं।

+0

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

+0

आपका मतलब एक ConcurrentLinkedQueue पर है, है ना? यह एक अच्छा सवाल है। मैं ConcurrentLinkedQueue पर अपने चिप्स शर्त लगाता हूं। :) लेकिन पाइप के बारे में एक फायदा यह है कि: आप एक संदेश भेजते हैं जैसे कि हर कोई कर रहा है, दूसरे शब्दों में, आप किसी ऑब्जेक्ट को कतार में लाने के बजाय चैनल से पढ़ते हैं। – chrisapotek

3

तो पाइप (check here) के साथ बहुत सारी परेशानी होने के बाद मैंने एनआईओ पाइप पर गैर-अवरुद्ध समवर्ती कतारों का पक्ष लेने का फैसला किया। तो मैंने जावा के ConcurrentLinkedQueue पर कुछ मानक बनाए। नीचे देखें:

public static void main(String[] args) throws Exception { 

    ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>(); 

    // first test nothing: 

    for (int j = 0; j < 20; j++) { 

     Benchmarker bench = new Benchmarker(); 

     String s = "asd"; 

     for (int i = 0; i < 1000000; i++) { 
      bench.mark(); 
      // s = queue.poll(); 
      bench.measure(); 
     } 

     System.out.println(bench.results()); 

     Thread.sleep(100); 
    } 

    System.out.println(); 

    // first test empty queue: 

    for (int j = 0; j < 20; j++) { 

     Benchmarker bench = new Benchmarker(); 

     String s = "asd"; 

     for (int i = 0; i < 1000000; i++) { 
      bench.mark(); 
      s = queue.poll(); 
      bench.measure(); 
     } 

     System.out.println(bench.results()); 

     Thread.sleep(100); 
    } 

    System.out.println(); 

    // now test polling one element on a queue with size one 

    for (int j = 0; j < 20; j++) { 

     Benchmarker bench = new Benchmarker(); 

     String s = "asd"; 
     String x = "pela"; 

     for (int i = 0; i < 1000000; i++) { 
      queue.offer(x); 
      bench.mark(); 
      s = queue.poll(); 
      bench.measure(); 
      if (s != x) throw new Exception("bad!"); 
     } 

     System.out.println(bench.results()); 

     Thread.sleep(100); 
    } 

    System.out.println(); 

    // now test polling one element on a queue with size two 

    for (int j = 0; j < 20; j++) { 

     Benchmarker bench = new Benchmarker(); 

     String s = "asd"; 
     String x = "pela"; 

     for (int i = 0; i < 1000000; i++) { 
      queue.offer(x); 
      queue.offer(x); 
      bench.mark(); 
      s = queue.poll(); 
      bench.measure(); 
      if (s != x) throw new Exception("bad!"); 
      queue.poll(); 
     } 

     System.out.println(bench.results()); 

     Thread.sleep(100); 
    } 
} 

परिणाम:

totalLogs=1000000, minTime=0, maxTime=85000, avgTime=58.61 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=5281000, avgTime=63.35 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=725000, avgTime=59.71 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=25000, avgTime=58.13 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=378000, avgTime=58.45 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=15000, avgTime=57.71 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=170000, avgTime=58.11 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=1495000, avgTime=59.87 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=232000, avgTime=63.0 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=184000, avgTime=57.89 (times in nanos) 

totalLogs=1000000, minTime=0, maxTime=2600000, avgTime=65.22 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=850000, avgTime=60.5 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=150000, avgTime=63.83 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=43000, avgTime=59.75 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=276000, avgTime=60.02 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=457000, avgTime=61.69 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=204000, avgTime=60.44 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=154000, avgTime=63.67 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=355000, avgTime=60.75 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=338000, avgTime=60.44 (times in nanos) 

totalLogs=1000000, minTime=0, maxTime=345000, avgTime=110.93 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=396000, avgTime=100.32 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=298000, avgTime=98.93 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=1891000, avgTime=101.9 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=254000, avgTime=103.06 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=1894000, avgTime=100.97 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=230000, avgTime=99.21 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=348000, avgTime=99.63 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=922000, avgTime=99.53 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=168000, avgTime=99.12 (times in nanos) 

totalLogs=1000000, minTime=0, maxTime=686000, avgTime=107.41 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=320000, avgTime=95.58 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=248000, avgTime=94.94 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=217000, avgTime=95.01 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=159000, avgTime=93.62 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=155000, avgTime=95.28 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=106000, avgTime=98.57 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=370000, avgTime=95.01 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=1836000, avgTime=96.21 (times in nanos) 
totalLogs=1000000, minTime=0, maxTime=212000, avgTime=98.62 (times in nanos) 

निष्कर्ष:

maxTime डरावना हो सकता है लेकिन मुझे लगता है कि यह समाप्त करने के लिए हम 50 nanos में हैं सुरक्षित है मतदान एक समवर्ती का योगदान देती कतार।

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