2014-11-06 20 views
8
private ExecutorService exec = Executors.newSingleThreadExecutor(r -> { 
    Thread t = new Thread(r); 
    t.setDaemon(true); // allows app to exit if tasks are running 
    return t ; 
}); 

मुझे समझने में कठिनाई हो रही है कि मैं एक निष्पादक के पीछे विचार समझता हूं, लेकिन पैरामीटर r मुझे भ्रमित कर रहा है। मैं प्रयोग किया है:जावा 8 लैम्ब्डा

final ExecutorService exec = Executors.newSingleThreadExecutor(r -> { 
     Thread t = new Thread(r); 
     System.out.println("Class of r: " + r.getClass()+ ". r to string: " + r.toString()); 
     System.out.println("Class of t: " + t.getClass() +". Name of t: "+ t.getName()); 
     t.setDaemon(true); 
     return t; 
    }); 

बेहतर जानकारी के लिए और परिणाम है:

Class of r: class java.util.concurrent.ThreadPoolExecutor$Worker. r to string: [email protected][State = -1, empty queue] 
Class of t: class java.lang.Thread. Name of t: Thread-3 

rThread वस्तु निर्माता के लिए एक पैरामीटर के रूप में पारित किया जा रहा है।

  1. सरल पत्र r कैसे यह दर्शाता है कि वस्तु पारित किया जा रहा एक ThreadPoolExecutor है?
  2. ThreadPoolExecutor पैरामीटर के रूप में पास करने योग्य कैसे है यदि यह को Thread's कन्स्ट्रक्टर द्वारा आवश्यकतानुसार लागू नहीं करता है?

यदि कोई मुझे कोड के गैर-लैम्ब्डा संस्करण प्रदान कर सकता है, तो यह मेरी समझ के लिए बहुत बड़ा लाभ होगा।

उत्तर

15

newSingleThreadExecutor एक थ्रेडफैक्टरी को तर्क के रूप में लेता है। ThreadFactory एक विधि को परिभाषित करता है newThread जो एक तर्क के रूप में एक रननेबल लेता है और एक थ्रेड देता है।

लैम्ब्डा आप के लिए और अधिक अर्थपूर्ण हो सकता है अगर हम स्पष्ट रूप से r के प्रकार निर्दिष्ट करें:

(Runnable r) -> { 
    Thread t = new Thread(r); 
    return t; 
} 

अब यह और अधिक स्पष्ट इस newThread के शरीर के लिए एक परिभाषा है।

यह छोड़कर कि चूंकि लैम्ब्डा को तुरंत थ्रेड फैक्ट्री स्वीकार करने वाली विधि के लिए तर्क के रूप में पारित किया जाता है, इसलिए संकलक यह अनुमान लगा सकता है कि r का प्रकार चलाना आवश्यक है। इसलिए इसे छोड़ा जा सकता है।

लैम्ब्डा बिना, इस कोड निम्नलिखित गुमनाम वर्ग परिभाषा और इन्स्टेन्शियशन करने के लिए अनुवाद:

private ExecutorService exec = Executors.newSingleThreadExecutor(
    new ThreadFactory() { 
     @Override 
     public Thread newThread(Runnable r) { 
      Thread t = new Thread(r); 
      t.setDaemon(true); 
      return t; 
     } 
    } 
); 

सरल पत्र r कैसे यह दर्शाता है कि वस्तु पारित किया जा रहा एक ThreadPoolExecutor है?

r का प्रकार रननेबल है क्योंकि लैम्ब्डा अभिव्यक्ति का लक्ष्य प्रकार इस तरह की एक विधि को परिभाषित करता है।

जिस वस्तु को आप पारित कर रहे हैं वह वास्तव में ThreadPoolExecutor$Worker है जो थ्रेडपूलएक्ससेलर का एक निजी आंतरिक वर्ग है जो रननेबल लागू करता है।

कैसे एक ThreadPoolExecutor एक पैरामीटर अगर यह Runnable को लागू नहीं करता है के रूप में प्रचलित Thread के निर्माता द्वारा के लिए आवश्यक है के रूप में?

ऊपर देखें (r एक रननेबल है)।

+0

धन्यवाद, रेडियोोडेफ़। मैं अब कोड को पूरी तरह से समझता हूं।मैं 'बाहरी क्लास $ आंतरिक क्लास' प्रकार नोटेशन - जावा भाषा विशिष्टता के बारे में और कहां से जान सकता हूं? – user465001

+2

मुझे इसे समझाने में खुशी है। '' '' के बारे में जानने के लिए भी बहुत कुछ नहीं है। जब आप कोड में घोंसले या आंतरिक वर्ग का संदर्भ लेते हैं तो आप 'बाहरी। आंतरिक' का उपयोग करते हैं, लेकिन आम तौर पर इसे वास्तव में 'बाहरी $ इनर' नामक कक्षा में संकलित किया जाता है। '$' सभी पहचानकर्ताओं के लिए एक वैध चरित्र है लेकिन इसे आमतौर पर आंतरिक तंत्र के लिए आरक्षित माना जाता है। http://stackoverflow.com/q/7484210/2891664 – Radiodef

+0

फिर से धन्यवाद, रेडियोोडेफ़! – user465001

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