2009-07-24 10 views
6

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

रननेबल ठीक काम करते हैं; कॉलबल्स हमेशा के लिए ब्लॉक लगते हैं, लेकिन मुझे यकीन नहीं है क्यों .... मुझे क्या याद आ रही है?

धन्यवाद!

public class ExecutorExample { 

    /** 
    * @param args 
    * @throws ExecutionException 
    * @throws InterruptedException 
    */ 
    public static void main(String[] args) throws InterruptedException, ExecutionException { 

     ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5); 

     FutureTask<ArrayList<String>> ft1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>(){ 
      @Override 
      public ArrayList<String> call() { 
       ArrayList<String> stuff = new ArrayList<String>(); 
       for(int i = 0;i<10;i++){ 
        String thing ="Adding " + i + " to result"; 
        stuff.add(thing); 
        System.out.println(thing); 

       } 
       return stuff; 
      }}); 

     scheduler.scheduleAtFixedRate(ft1, 0, 1, TimeUnit.SECONDS); 

     System.out.println(ft1.get()); 
     System.out.println(ft1.isDone()); 

    } 
} 

उत्तर

8

समस्या यह है कि FutureTask प्रयोग किया जाता है, और के रूप में अपने वर्ग प्रलेखन कहते हैं, कि "गणना पूरा कर लिया है एक बार, अभिकलन को पुन: प्रारंभ नहीं किया जा सकता या रद्द कर दिया।"

FutureTask की विधि के बाद एक बार लागू किया गया है, बाद में आमंत्रण तुरंत वापस लौटाता है, बिना कार्य के Callable उदाहरण के प्रतिनिधि के बिना।

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

+1

मुझे यकीन नहीं है कि मैं इसका अनुसरण करता हूं। फ्यूचरटास्क लागू करने योग्य लागू करता है, और मैं उम्मीद करता हूं कि यह कॉल() विधि को कॉल करे और परिणाम संग्रहित करे। मैं तब उम्मीद करता हूं कि जब तक काम पूरा नहीं हो जाता है, या कैश किए गए परिणाम को तुरंत वापस कर दें। तो शेड्यूलर फ्यूचरटास्क नहीं चलाएगा, जिसके परिणामस्वरूप कॉल() और परिणाम बाद में एकत्रित होने के लिए कैश किया जा रहा है? –

+1

हां, लेकिन केवल एक बार। पहले के बाद कोई भी निर्धारित आमंत्रण फ़्यूचरटास्क पर 'रन' कहलाएगा, लेकिन कॉलबल पर 'कॉल' का आह्वान किए बिना वह रन विधि "शॉर्ट-सर्किट"। लेकिन शेड्यूलर इस बारे में अवगत नहीं है, और फ्यूचरटास्क का आह्वान करने के लिए दौड़ता रहता है, इसलिए प्रोग्राम समाप्त नहीं होता है। – erickson

+0

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

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