2012-10-19 42 views
5

के साथ कमजोर संदर्भ जावा में एक कमजोर संदर्भ बनाने के लिए संभव है जिसका ऑब्जेक्ट केवल कचरा कलेक्टर को भेजा जा सकता है यदि कोई निर्दिष्ट स्थिति true लौटाती है?एक शर्त/टाइमआउट

कहते हैं कि मैं एक कैश जो कुछ आंकड़ों के आईडी नंबर के नक्शे की तरह कुछ करते हैं:

Map<Integer, SomeData> cache = new HashMap<>(); 

SomeData दो महत्वपूर्ण तरीकों - void updateTime(), जो सिर्फ वर्तमान समय के एक आंतरिक चर सेट, और boolean canBeDeleted(), जो यह जांचता है कि ऑब्जेक्ट का पिछले 10 मिनट में उपयोग किया गया है या नहीं (बस वर्तमान समय और सहेजे गए समय की तुलना करके 10 मिनट)। यह समय की इस निश्चित राशि के लिए इस्तेमाल नहीं किया गया है, विधि रिटर्न true और वस्तु कैश से हटाया जा सकता है ...

हालांकि, जब मैं मजबूत करने के बजाय कमजोर संदर्भों के साथ एक कैश बनाएँ:

Map<Integer, WeakReference<SomeData>> cache = new HashMap<>(); 

तो केवल एक चीज WeakReference चेकों शायद वस्तु के लिए संभव मजबूत संदर्भ हैं, लेकिन अगर यह भी मेरी हालत canBeDeleted() की जाँच की और संदर्भ को नहीं निकाला, अगर यह false लौटे मैं करना चाहते हैं। क्या ऐसा करने का कोई तरीका है?

(इसके शीर्ष पर, एक स्मृति रिसाव है और मुझे यकीन नहीं है कि इसे कैसे हल किया जाए ... जब वीक रेफरेंस के अंदर ऑब्जेक्ट हटा दिया जाता है, तो मानचित्र में अभी भी अनावश्यक कुंजी/मान जोड़ी होती है)।

अग्रिम धन्यवाद।

+0

आप पर [ 'अमरूद caches'] देखें, तो (http://code.google.com/p/guava-libraries/wiki/कैश एक्स्प्लेन्टेड), आप एक ऐसा बना सकते हैं जो स्वचालित रूप से उन प्रविष्टियों को हटा देता है जिन्हें किसी दिए गए समय में संदर्भित नहीं किया गया है। – Keppil

+0

"()" में समस्या के लिए: आपको अभी भी अपना नक्शा साफ़ करना होगा। WeakRef के क्लाइंट को हटाने से मानचित्र प्रविष्टि को स्वतः हटाया नहीं जाएगा। – Fildor

उत्तर

0

आप केवल उस कैश में कुंजी को हटा सकते हैं जहां स्थिति सत्य है।

+0

मुझे पता है, लेकिन फिर मुझे एक अलग धागा होना चाहिए जो उदाहरण के लिए हर 10 मिनट में कैश के माध्यम से जाएगा और सब कुछ अनावश्यक हटा देगा।लेकिन अगर मैं संभव हो तो कचरा कलेक्टर के साथ किसी अन्य तरह के सहयोग से ऐसा करना और ऐसा करना पसंद करूंगा। –

+0

यदि आप यह जांचना चाहते हैं कि आपकी हालत 'सत्य' लौटाती है, तो आपको कैश से गुजरना होगा, वैसे भी। यह काफी अस्पष्ट है कि आप क्या हासिल करना चाहते हैं। –

2

आप LinkedHashMap#removeEldestEntry का उपयोग कर सकते हैं हालांकि यह आपको कैश के अंदर समय प्रविष्टि की मात्रा के आधार पर निकालने का तरीका प्रदान नहीं करता है, यह आपको प्रविष्टियों को हटाने या नहीं करने के आधार पर प्रविष्टियों को हटाने का एक तरीका प्रदान करता है।

यह प्रत्येक बार एक नया जोड़ा जाने पर सबसे बड़ी प्रविष्टि को हटाने का अवसर प्रदान करता है। यह नक्शा उपयोगी है यदि नक्शा कैश का प्रतिनिधित्व करता है: यह मानचित्र को पुरानी प्रविष्टियों को हटाकर स्मृति खपत को कम करने की अनुमति देता है।

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { 
    return size() > limit; 

इसके अलावा, आप accessOrdertrue साथ LinkedHashMap प्रारंभ करने की आवश्यकता याद है।

एक्सेसऑर्डर - ऑर्डरिंग मोड - प्रवेश-आदेश के लिए सही, प्रविष्टि-आदेश के लिए गलत।

तो यह सब एक साथ डाल स्रोत होना चाहिए की तरह नीचे

public class Cache<K, V> extends LinkedHashMap<K, V> { 
    private final int MAX_ENTRIES = 100; 
    public Cache() { 
     super(16, 0.75f, true);// accessOrder is true 
    } 
    @Override 
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { 
     return size() > MAX_ENTRIES; 
    } 
}