2011-09-04 9 views
7

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

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

+1

क्यों आप बच्चे थ्रेड धागा स्थानीय मूल्य समाशोधन रहे हैं यदि आप इसे बाद में की आवश्यकता है? क्या अगले पैर पर किसी भिन्न पैरेंट थ्रेड से मूल्यों की आवश्यकता होती है या क्या बच्चे के धागे को पहली बार बनाए जाने के बाद वे माता-पिता में बदल गए हैं? –

+0

@ बर्ट - यही कारण है कि। असल में मैं धागे स्थानीय चर में एक अनुरोध आईडी संग्रहीत कर रहा हूं जो बाल धागे के कई प्रयोगों में बदल जाता है। प्रतिक्रिया के लिए – neesh

उत्तर

4

ऐसा लगता है कि यह थ्रेड-लोकल के "विरासत" स्वाद के लिए एक खराब उपयोग-मामला है।

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

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


मुझे लगता है मैं क्या पूछ रहा हूँ अगर वहाँ एक बच्चे को धागे से माता-पिता थ्रेड धागा स्थानीय चर के मूल्य तक पहुंचने का मार्ग है।

ऐसा करने का कोई तरीका नहीं है।

और, आपकी अन्य टिप्पणियों का निर्धारण करते हुए, मुझे संदेह है कि आपका मतलब "माता-पिता" और "बच्चा" सामान्य अर्थ में है ... जहां मूल धागा बच्चे के धागे को बनाता है।

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

+1

धन्यवाद। मैं उत्सुक हूं कि मैं बच्चे के थ्रेड के धागे-स्थानीय को कैसे शुरू कर सकता हूं। मुझे लगता है कि मैं क्या पूछ रहा हूं कि अगर बच्चे के थ्रेड से पैरेंट थ्रेड के थ्रेड स्थानीय चर के मूल्य तक पहुंचने का कोई तरीका है। – neesh

+0

दुर्भाग्यवश यह उत्तर समस्या को खुलता है। एक थ्रेड स्थानीय को एक थ्रेड से दूसरे थ्रेड में कैसे स्थानांतरित किया जा सकता है।यदि कोई दूसरे का बच्चा है तो इनहेरटेबल थ्रेडलोकल्स अच्छी तरह से काम करते हैं, लेकिन थ्रेड पूल के मामले में आप क्या करते हैं? – Gregor

+0

आपने उत्तर को क्यों कम किया? यह एक जवाब को कम करने के लिए कठोर है जो कहता है कि कोई अच्छा समाधान मौजूद नहीं है ... सिर्फ इसलिए कि आप उस तथ्य को पसंद नहीं करते हैं। निश्चित रूप से, यह आपको मेरी मदद करने के लिए प्रोत्साहित नहीं करता है! –

0

कॉलर के थ्रेड में एक रननेबल रन का निर्माता, जबकि रन विधि बच्चे के धागे में चलती है। आप माता-पिता से बच्चे के धागे में जानकारी स्थानांतरित करने के लिए इस तथ्य का उपयोग कर सकते हैं। देखें:

public class ThreadlocalApplication { 
static public ThreadLocal<String> tenantId = new ThreadLocal<>(); 

public static void main(String[] args) throws ExecutionException, InterruptedException { 
    ExecutorService executor = Executors.newCachedThreadPool(); 
    System.out.println(Thread.currentThread().getName()); 
    ThreadlocalApplication.tenantId.set("4711"); 
    executor.submit(new AsyncTask()).get(); 
    executor.shutdown(); 
} 

static class AsyncTask implements Runnable { 
    private String _tenantId; 

    public AsyncTask() { 
     System.out.println(Thread.currentThread().getName()); 
     _tenantId = ThreadlocalApplication.tenantId.get(); 
    } 

    @Override 
    public void run() { 
     ThreadlocalApplication.tenantId.set(_tenantId); 
     System.out.println(Thread.currentThread().getName()); 
     System.out.println(ThreadlocalApplication.tenantId.get()); 
    } 
} 
} 

और यह परिणाम

main 
main 
pool-1-thread-1 
4711