2012-05-04 8 views
6

जहां तक ​​मेरा java.lang.Thread डॉक्स से, और "How to access a Runnable object by Thread?" और "Get current instance of Runnable" की तरह अन्य प्रश्न यहाँ stackoverflow पर तैनात से, समझ सकते हैं यह संभव नहीं Runnable वस्तु एक Thread में एम्बेडेड के लिए एक संदर्भ पाने के लिए है।थ्रेड में चलने योग्य रननेबल क्यों संभव नहीं है?

एक परिदृश्य जहां यह संभावना उपयोगी होगी, एक विधि को कार्यान्वित करते समय, जिसका हस्ताक्षर संशोधित नहीं किया जा सकता है क्योंकि हम किसी अन्य वर्ग या इंटरफ़ेस में परिभाषित विधि को ओवरराइड कर रहे हैं, और विभिन्न संचालन के आधार पर किया जाना चाहिए वर्तमान Thread में एम्बेडेड Runnable का प्रकार।

अगर हम उदाहरण के लिए था एक विधि Thread कक्षा में getRunnable कहा जाता है हम कुछ इस तरह कर सकता है:

if (Thread.currentThread().getRunnable() instanceof Type1) { 
    // do something... 
} else { 
    // do something else... 
} 

यह उन परिस्थितियों में भी उपयोगी हो सकता है जब हम एक विधि में निहित संचालन कर रहे हैं सुनिश्चित करना चाहते हैं केवल कुछ धागे द्वारा निष्पादित और दूसरों द्वारा नहीं।

तो मैं सोच रहा था, क्या जावा डेवलपर्स ने से Runnable उदाहरण प्राप्त करने की अनुमति देने का कोई विशिष्ट कारण नहीं है, या क्या यह एक लापता विशेषता है जिसे अधिसूचित किया जा सकता है? अगर आपको लगता है कि उस विकल्प के पीछे कोई कारण नहीं है लेकिन इसे अनुपलब्ध फीचर के रूप में सूचित करने के लायक नहीं है, तो ऊपर वर्णित परिदृश्य में आप किस रणनीति का उपयोग करेंगे?

+0

क्या 'main' विधि के साथ मुख्य थ्रेड के लिए" runnable "हो सकता है? –

+2

@ किर्कवॉल, 'नल'? –

+4

आपके उदाहरण में जैसे 'exampleof' के परिणाम पर ब्रांचिंग लगभग एक अच्छा विचार नहीं है। – NPE

उत्तर

11

तो मैं सोच रहा था, एक विशेष कारण है कि जावा डेवलपर्स एक धागा

यह शायद सिर्फ एक आवश्यकता थी से Runnable उदाहरण प्राप्त करने के लिए अनुमति नहीं करने का फैसला किया है। Runnable स्वयं अपनी कक्षा की पहचान करने में सक्षम होना चाहिए ताकि विचार यह है कि उसे यह जानकारी अजीब है। यह एक सुरक्षा भी हो सकती है ताकि अन्य धागे को किसी अन्य धागे में चलने वाले वर्ग तक पहुंच न हो।

यदि आपको अपने आवेदन के अन्य हिस्सों से वर्तमान Runnable तक पहुंच की आवश्यकता है तो मैं ThreadLocal<Runnable> का उपयोग करने की अनुशंसा करता हूं। आपके run() विधि में आप इसे सेट कर सकते हैं और फिर इसे अपने अन्य वर्गों में पुनर्प्राप्त कर सकते हैं। हालांकि आपको ThreadLocal कहीं वैश्विक रूप से सुलभ रखना होगा।

आप वर्तमान स्टैक ट्रेस को Runnable कक्षा को समझने के लिए भी संसाधित कर सकते हैं जो एक हैक से भी अधिक है लेकिन यह काम करेगा।

Thread रों है कि उन्हें क्रियान्वित कर रहे हैं (या तो एक Map<Thread, Runnable> के साथ या एक ThreadLocal<Runnable> के साथ)
उपयोग प्रतिबिंब करने के लिए अपने Runnable रों की मैपिंग रखें:

5

एक जोड़े दृष्टिकोण आप इस के आसपास पाने के लिए ले सकता है कर रहे हैं Thread से Runnable तक पहुँचने के लिए:

private static final Field target; 
static { 
    Field f = null; 
    try { 
     f = Thread.class.getDeclaredField("target"); 
     f.setAccessible(true); 
    } catch (NoSuchFieldException e) { 
     // might happen in a different version of Java (works in Java 7) 
     e.printStackTrace(); 
    } 
    target = f; 
} 

public static Runnable getTarget(Thread t) { 
    try { 
     return (Runnable) target.get(t); 
    } catch (IllegalAccessException e) { 
     // shouldn't happen, we already made the field accessible when we created it 
     e.printStackTrace(); 
     } 
    return null; 
} 
0

वहाँ एक अप्रत्यक्ष विधि यह मदद मिलेगी हो सकता है, आप स्टैक ट्रेस मिल सकती है।

StackTraceElement[] stackTraceElement = thread.getStackTrace(); 
for(StackTraceElement e :stackTraceElement){ 
    System.out.println("Trace "+e.getClassName()); 
} 

आउटपुट:

ट्रेस java.lang।थ्रेड

ट्रेस com.emc.multithreading.RunnableDemo

ट्रेस java.lang.Thread

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