2008-09-17 15 views
10

पर कॉल करना यह थ्रेड के लिए कानूनी है। इसे अपने कन्स्ट्रक्टर के अंदर .start() को कॉल करने के लिए कानूनी है? और यदि ऐसा है तो संभावित कारण क्या हो सकते हैं? मैं समझता हूं कि ऑब्जेक्ट पूरी तरह से शुरू नहीं हुआ है जब तक कि कन्स्ट्रक्टर पूरा नहीं हो जाता है लेकिन इसके अलावा कोई अन्य समस्याएं हैं?थ्रेड.स्टार्ट() को अपने स्वयं के कन्स्ट्रक्टर

उत्तर

1

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

2

मुझे लगता है कि आप अपना कोड कम वर्बोज़ बनाने के लिए ऐसा करना चाहते हैं; बजाय

Thread t = new CustomThread(); 
t.start(); 
activeThreads.add(t); 

कहने का तुम सिर्फ कह सकते हैं

activeThreads.add(new CustomThread()); 

मैं भी कम शब्दाडंबर होने, लेकिन मैं अन्य उत्तरदाताओं कि आप ऐसा नहीं करना चाहिए के साथ सहमत हैं। विशेष रूप से, यह सम्मेलन तोड़ता है; जावा के साथ परिचित कोई भी जो दूसरे उदाहरण को पढ़ता है, यह मान लेगा कि धागा शुरू नहीं हुआ है। इससे भी बदतर, अगर वे अपना खुद का थ्रेडिंग कोड लिखते हैं जो आपके साथ किसी तरह से बातचीत करता है, तो कुछ धागे को start पर कॉल करने की आवश्यकता होगी और अन्य नहीं होंगे।

यह आपके द्वारा काम कर रहे समय में आकर्षक लग रहा है, लेकिन अंत में आपको अन्य लोगों के साथ काम करना होगा, और अच्छी कोडिंग आदतों को विकसित करना अच्छा होगा ताकि आपके पास दूसरों के साथ काम करने में आसान समय लगेगा और मानक सम्मेलनों के साथ लिखा कोड।

हालांकि, यदि आप सम्मेलनों की परवाह नहीं करते हैं और अतिरिक्त शब्दकोष से नफरत करते हैं, तो आगे बढ़ें; यह किसी भी समस्या का कारण नहीं होगा, भले ही आप गलती से start कई बार कॉल करने का प्रयास करें।

2

वैसे, अगर एक कम शब्दाडंबर चाहता है और अभी भी अपने "मानक" अर्थ विज्ञान के साथ निर्माता रखने के लिए, एक एक कारखाने विधि बना सकते हैं:

activeThreads.add(CustomThread.newStartedThread()); 
+0

ओपी के सवाल से यह कैसे प्रासंगिक है? – subsub

1

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

यदि आपकी कक्षा आंतरिक रूप से थ्रेड का उपयोग करती है, तो उस थ्रेड का अस्तित्व सार्वजनिक API में दिखाई नहीं देना चाहिए। यह सार्वजनिक एपीआई को प्रभावित किए बिना सुधार की अनुमति देता है। समाधान: चलने योग्य नहीं, थ्रेड का विस्तार करें।

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

कम verbosity के लिए मैं एक कारखाने विधि (उदाहरण के लिए Foo.createAndRunInThread()) का उपयोग करने के लिए सुझाव दूसरा।

13

स्मृति-सुरक्षा कारणों के लिए, आपको किसी ऑब्जेक्ट के संदर्भ या उस ऑब्जेक्ट के फ़ील्ड्स को किसी अन्य थ्रेड पर अपने कन्स्ट्रक्टर के भीतर से बेनकाब नहीं करना चाहिए। यह मानते हुए कि आपके कस्टम थ्रेड में इंस्टेंस वैरिएबल हैं, इसे कन्स्ट्रक्टर के भीतर से शुरू करके, आपको जावा मेमोरी मॉडल दिशानिर्देशों का उल्लंघन करने की गारंटी है। अधिक जानकारी के लिए Brian Goetz's Safe Construction Techniques देखें।

+1

इस उत्तर पर टिप्पणियाँ? यह गलत नहीं है। –

+1

डाउनवोट? अगर आपको लगता है कि यह गलत है तो कृपया एक स्रोत साइट करें। यह सही है। –

+0

उत्तर बिल्कुल डिब्बाबंद नहीं है। जब तक आप रननेबल कन्स्ट्रक्टर का उपयोग नहीं करते हैं, तो आप कन्स्ट्रक्टर पूर्ण होने से पहले 'थ्रेड # रन' के भीतर से 'this' को संदर्भित कर सकते हैं, जो मेमोरी सुरक्षा नियमों का उल्लंघन करता है। इस प्रकार, आपको सावधान रहना चाहिए। –

3

यदि थ्रेड क्लास को और भी उप-वर्गीकृत किया गया है तो आपको भी गंभीर समस्याएं दिखाई देगी। उस स्थिति में, सुपर() से बाहर निकलने के बाद आप पहले से चलने वाले थ्रेड के साथ समाप्त हो जाएंगे, और इसके कन्स्ट्रक्टर में उप-वर्ग कुछ भी हो सकता है।

@ बिल बार्क्सडेल यदि थ्रेड पहले से चल रहा है, तो कॉलिंग शुरू करने से आपको एक अवैध थ्रेडस्टेट अपवाद मिल जाता है, आपको 2 धागे नहीं मिलते हैं।

1

कानूनी ... हाँ (कहीं और बताए गए चेतावनी के साथ)। सलाहकार ... नहीं।

मैं सिर्फ एक गंध है जिसे आप केवल आसानी से बच सकते हैं। यदि आप अपने धागे को स्वतः शुरू करना चाहते हैं, तो बस इसे Heinz Kabutz जैसा करें।

public class ThreadCreationTest { 
    public static void main(String[] args) throws InterruptedException { 
    final AtomicInteger threads_created = new AtomicInteger(0); 
    while (true) { 
     final CountDownLatch latch = new CountDownLatch(1); 
     new Thread() { 
     { start(); } // <--- Like this ... sweet and simple. 
     public void run() { 
      latch.countDown(); 
      synchronized (this) { 
      System.out.println("threads created: " + 
       threads_created.incrementAndGet()); 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       Thread.currentThread().interrupt(); 
      } 
      } 
     } 
     }; 
     latch.await(); 
    } 
    } 
} 
संबंधित मुद्दे