2011-07-05 32 views
5

सबसे सरल रूप में, निम्नलिखित डिज़ाइन है:क्या जावा में सी ++ विनाशक बराबर है?

class Session { 
    Timer t = new Timer(); 
    // ... 
}; 

जब भी, Session आवंटित किया जाता है, तो मैं इसके अंदर एक टाइमर शुरू करता हूं; टाइमर 10-20 मिनट के बाद समाप्त हो जाएगा। अब, मान लीजिए कि टाइमर समाप्त होने से पहले Session नष्ट हो गया है; तो यह एक परिदृश्य है जहां मुझे टाइमर बंद करना होगा। मुझे नहीं पता कि क्या कोई आखिरी विधि है जिसे हमेशा Session नष्ट होने पर बुलाया जाता है।

जावा में समकक्ष सी ++ विनाशक का कुछ प्रकार है, जो Session को नष्ट करने पर cancel() टाइमर में मदद करता है? (जीसी के लिए इंतजार किए बिना)

संपादित करें: कृपया C++ के लिए पुनः प्रयास न करें। मैं उस समकक्ष के कुछ चाहता था। Xzx20 एक फोन सत्र है जो नष्ट हो जाता है जब उससे जुड़े सभी उपयोगकर्ता डिस्कनेक्ट होते हैं। अब, कोई Session विधि नहीं है जिसे अंतिम रूप से बुलाया जाता है और न ही कोई अपवाद है।

उत्तर

6

नहीं, जावा में बनी ऐसी कोई बात नहीं है ने सुझाव दिया। निकटतम एक फाइनलाइज़र लिखना है, लेकिन इसकी कोई गारंटी नहीं है कि यह दौड़ जाएगा।

सत्र कैसे नष्ट हो जाता है? यदि कोई विधि कहा जाता है, तो हर तरह से कोड डाल दें।

आप सत्र कैसे बनाते हैं? यदि आप इसे एक कोशिश/पकड़ ब्लॉक में करते हैं, तो आप आखिरकार ब्लॉक में सबकुछ साफ कर सकते हैं।

मैं एक करीबी() विधि लिखूंगा जिसने इसका ख्याल रखा और अंततः ब्लॉक में इसे कॉल किया।

+1

कोशिश करें ... आखिरकार यह सुनिश्चित करने का तरीका है कि आपका साफ-सुथरा ("विनाशक") कोड बुलाया जाए। – qbert220

0

जावा में ऐसा कोई तरीका नहीं है। finalize() विधि, शीर्ष-स्तर Object में परिभाषित विधि, कचरा कलेक्टर द्वारा ऑब्जेक्ट को नष्ट होने पर लागू किया जा सकता है, लेकिन यह ऐसा व्यवहार नहीं है जिस पर आप भरोसा कर सकते हैं।

सबसे अच्छा आप केवल ऑब्जेक्ट को शून्य (संदर्भ को हटा सकते हैं) सेट कर सकते हैं, जो इसे कचरा संग्रह के लिए तैयार कर देगा।

2

सी ++ के विपरीत, आप जावा में ऑब्जेक्ट डिलोकेशन को नियंत्रित नहीं कर सकते हैं - यानी, जब भी यह फिट दिखाई देता है तो जीसी ऑब्जेक्ट्स एकत्र करता है, केवल यह गारंटी देता है कि यह किसी भी संदर्भ में किसी भी संदर्भ के माध्यम से पहुंचा जा सकता है पहर।

Object.finalize() है, जो क्लीनअप करने के लिए आखिरी मौका हुक के रूप में कार्य करता है, लेकिन रनटाइम गारंटी नहीं देता है कि इसे बिल्कुल भी कहा जाता है।

मैं डिजाइन पर पुनर्विचार करता हूं और अपने टाइमर को साफ करने के एक और स्पष्ट तरीके से आने का प्रयास करता हूं।

2

जावा में, चर सीधे सी ++ में किए गए ऑब्जेक्ट्स का प्रतिनिधित्व नहीं करते हैं - जावा में वेरिएबल्स ऑब्जेक्ट्स के संदर्भ हैं। तो एक वस्तु दायरे से बाहर नहीं जा सकती - केवल एक चर जो किसी वस्तु को संदर्भित करता है, गुंजाइश से बाहर जा सकता है।

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

1

पहला, finalize एक विनाशक के बराबर नहीं है। कोशिश मत करो और इसे एक के रूप में उपयोग करें; यह काम नहीं करेगा। इसके लिए जावा में कुछ भी नहीं बनाया गया है, लेकिन कुछ सर्किलों में, इसके लिए void dispose() का उपयोग करने के लिए एक सम्मेलन है; delete ptr; के बजाय, आप ptr.dispose() लिखते हैं। (निश्चित रूप से, स्मृति को बाद में पुनः प्राप्त किया जाता है।) ऐसे मामलों में, finalize को परिभाषित करने का एक अच्छा विचार है, अगर dispose से पहले ऑब्जेक्ट को पुनः दावा किया जाता है तो कुछ प्रकार की आंतरिक त्रुटि उत्पन्न होती है।

1

अधिकांश समय आप समस्या का निर्माण कर सकते हैं ताकि आपको विनाशक की आवश्यकता न हो।

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

इस मामले में आप सरलता के लिए सिंगलटन शेड्यूल्ड एक्स्सेलर सेवा प्राप्त कर सकते हैं।

class Session { 
    private static final ScheduledExecutorService timer = 
            Executors.newSingleThreadScheduledExecutor(); 
    private Future<Void> timeoutFuture = null; 

    // call every time you want the timeout to start from now. 
    public void resetTimer() { 
     if(timeoutFuture != null) timeoutFuture.cancel(false); 
     timeoutFuture = timer.schedule(new Callable<Void>() { 
      public Void call() { 
       sessionTimedOut(); 
       return null; 
      } 
     }, TIMEOUT_SECONDS, TimeUnit.SECONDS); 
    } 

    void sessionTimedOut() { 
     // what to do when the session times out. 
    } 
} 

यहाँ महंगा घटक, ScheduledExecutorService एक बार बनाया है और आवेदन के जीवन के लिए रहती है। जब सत्र साफ हो जाता है (और कार्य समाप्त हो गया है)

+0

+1 दिलचस्प, 'ScheduledExecutorService' के बारे में सब कुछ क्या है। क्या आप अपना उत्तर थोड़ा और विस्तार से बता सकते हैं? – iammilind

+0

मैंने एक उदाहरण जोड़ा है। –

0

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

उपयोग उचित @ ... Scoped (ApplicationScoped, SessionScoped आदि) अपनी कक्षा पर एनोटेशन, जैसा कि आप जैसे पसंद करते हैं

.: कुछ विधि एनोटेट में क्या आप निर्माता में करना चाहता था क्या साथ @PostConstruct:

@PostConstruct 
private void initializeObjectsOrConnections() { 
    // ... 
} 

साथ @Inject अन्य स्थानों पर एनोटेशन अपने ऑब्जेक्ट सम्मिलित करें (यदि आप वान टी के लिए):

public class MyApplication { 

    @Inject 
    MyDatabaseFactory databaseFactory; 

    // ... 
} 

सफाई, डेटाबेस से वस्तुओं और डिस्कनेक्ट नष्ट - क्या आप MyDatabaseFactory वर्ग के @PreDestroy, जैसे .:

@PreDestroy 
private void destroyObjectsOrCloseConnections() { 
    // ... 
} 
साथ एनोटेट विधि में C++ से नाशक में करना चाहता था

इसका उपयोग करना बहुत आसान है और हमारे पास जावा में सी ++ से विनाशक के बराबर है।

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