2012-02-20 15 views
5

मैं निम्नलिखित गलती की:क्या एक्जिक्यूटर्स सर्विस को रिकर्सिवली बनाने का कोई तरीका है?

  1. नामक Executors.newFixedThreadThreadPool एक पूल
  2. Callable वस्तुओं, की एक सूची सेट अप करने के लिए ऐसी है कि बदले में call विधि बहुत ही थ्रेड पूल पर एक कार्य शुरू करने की कोशिश
  3. थे साथ invokeAll

परिणाम कतार में उन्हें डंप executo की कतार पर एक गतिरोध आर सेवा।

मैंने जो जावाडोक पढ़ा है वह गतिविधियों के इस सेट को प्रतिबंधित नहीं करता है। क्या मैं कुछ भुल गया? क्या कतार या सेवा को अनुकूलित करने का कोई तरीका है ताकि यह काम कर सके?

+0

मैं एक ऐसी ही सवाल था। मान लें कि मेरे थ्रेड पूल में केवल एक ही धागा है। मेरा बाहरी कॉल करने योग्य थ्रेड प्राप्त करता है और कॉल करने योग्य उप-कार्य को आमंत्रित करता है। यह फिर उप-कार्य को पूरा करने की प्रतीक्षा करता है। हालांकि, चूंकि पूल में एकमात्र धागा पहले से ही बाहरी कार्य से जुड़ा हुआ है, इसलिए इसे कभी भी आंतरिक कार्य को सौंपा नहीं जाएगा, जिसके परिणामस्वरूप डेडलॉक होगा। क्या यह मूल्यांकन सही है, या क्या मुझे कुछ याद आ रहा है? –

+0

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

उत्तर

3

आपके प्रश्न की मेरी समझ निम्न परीक्षण-मामले की तरह कुछ है, जो दस्तावेज के रूप में काम करती है (जैसा कि आप कहते हैं) और मैंने खुशी से उत्पादन में उपयोग किया है। आपका उदाहरण इस से अलग कैसे है?

import java.util.Date; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

class Scratch { 
    public static void main(String[] args) throws InterruptedException { 
     final ExecutorService pool = Executors.newFixedThreadPool(1); 
     pool.submit(new Callable<Void>() { 
      @Override 
      public Void call() throws Exception { 
       pool.submit(new Callable<Void>() { 
        @Override 
        public Void call() throws Exception { 
         System.out.println(new Date() + ": Second callable being run."); 
         pool.shutdown(); 
         return null; 
        } 
       }); 

       System.out.println(new Date() + ": First callable going to sleep..."); 
       Thread.sleep(2000); 
       System.out.println(new Date() + ": First callable finished!"); 
       return null; 
      } 
     }); 

     pool.awaitTermination(2, TimeUnit.MINUTES); 
    } 
} 

प्रिंटों कुछ की तरह:

Mon Feb 20 01:18:00 GMT 2012: First callable going to sleep... 
Mon Feb 20 01:18:02 GMT 2012: First callable finished! 
Mon Feb 20 01:18:02 GMT 2012: Second callable being run. 
+0

मेरा बाहरी फ़ंक्शन pool.invokeAll का उपयोग कर रहा है, पूल.submit नहीं, इसलिए यह प्रतीक्षा कर रहा है। और मुझे अब संदेह है कि समस्या यह है कि सभी धागे 'बाहरी' धागे पर उपयोग किए जाते हैं, इसलिए कोई काम अंदर नहीं किया जाता है। दूसरे शब्दों में, मैं मूर्ख था। – bmargulies

+0

फिर भी, एक निष्पादन योग्य कॉल करने योग्य अभी भी एक नया कॉल करने योग्य (सबमिट '('' 'सबमिट करने में सक्षम होना चाहिए) (' submit') 'newFixedTreadPool()' पर कभी भी ब्लॉक नहीं करता है? जब तक आप Callables के अंदर 'pool.invokeAll()' का उपयोग नहीं कर रहे थे? – FauxFaux

+0

वह ल्यूसीन के अंदर है और मुझे नहीं पता। लेकिन अगर सभी धागे का इस्तेमाल बाहरी पर किया जाता है, तो अंदरूनी जमा हो सकती है, लेकिन कभी प्रगति नहीं होती है, और फिर बाहरी लोगों में से कोई भी कभी पूरा नहीं होगा। – bmargulies

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