استراتيجية في جافا لتنظيف / إزالة عناصر الخريطة غير المستخدمة

StackOverflow https://stackoverflow.com/questions/1661109

سؤال

أقوم بتنفيذ "Manager" في تطبيق الويب الخاص بي الذي يمكن استدعاؤه لتعيين والحصول على سياق موقع الويب الذي يوجد به الخيط الحالي في (نحن علامة بيضاء موقعنا بحيث تمثل سياق موقع الويب الذي نحن عليه)

أحاول أن أعمل أفضل استراتيجية للقيام بذلك، حاليا أقوم حاليا بتنفيذ متجر المواضيع على WebSitecontexts في خريطة التجزئة المتزامنة:

private final ConcurrentHashMap<Thread, WebSiteContext> chm = new ConcurrentHashMap<Thread, WebSiteContext>();

في بداية الموضوع (إما من خلال مرشح Servlet أو من خلال إعداده يدويا)، سيتم ربط مؤشر الترابط ب WebSiteContext،

ولكن ترغب في تنظيف الخريطة لتجنب تسرب الذاكرة. لذلك أعتقد أن استراتيجية واحدة هي التكرار من خلال مفاتيح الخطر في الخريطة لمعرفة ما إذا كانت مؤشرات الترابط "حية" (خيط .Isalive ()) وإذا لم يزيلها على سبيل المثال مثل هذا:

 public class Cleaner implements Runnable {
      private static final int INTERVAL = 6 * 1000; // 6 seconds
      public Cleaner() {
      }
      public void run() {
            // soo every interval iterate through the threads if they're dead then remove it from the map.
            while(true) {
               try {
                     Set<Thread> threads = chm.keySet();
                     Set<Thread> staleThreads = new HashSet<Thread>();
                     for (Thread tmpThread : threads) {

                        // if we get to a dead thread then clean the fucker up
                        if (!tmpThread.isAlive()) {
                           // think that we're going to get a run condition anyway
                           chm.remove(tmpThread);
                        }
                     }
                  Thread.sleep(INTERVAL);
               } catch (Exception e) {
                  log.error("caught exception e:", e);
               }
            }
      }
   }

, ، ولكن هذا أعتقد أن أطلب مني مزامنة الوصول إلى الخريطة (أو يفعل ذلك؟) وهو شيء أريد تجنبه.

هل هناك أي نمط "اصطلاحي" لسمات تخزينه في خيوط جافا أو خرائط تنظيف بالفعل لديها كائنات مؤشر ترابط كمفاتيح؟ أنا منفتح لاستخدام الضعيف / softreferences أو في الواقع إذا كان هناك بعض ما يعادل الخيط .getcurrentthread (). Setattribute (كائن، كائن)، سيكون ذلك رائعا

هتاف سيمون ب

هل كانت مفيدة؟

المحلول

قد يعمل نهجك ولكنك ستنتهي بك الأمر بأكمل المزيد من العمل من Needed. threadlocal. هو ما تبحث عنه. سيتيح لك ذلك تخزين الكائنات المتعلقة بكل مؤشر ترابط في التطبيق الخاص بك. الطريقة النموذجية لاستخدامها هي تطبيق الأسلوب InitialValue () الذي يعينه القيمة الأولى. مثال:

 private static final ThreadLocal<String> localAttribute = new ThreadLocal<String> () {
         protected Integer initialValue() {
             return "InitialValue";
     }
 };

سيعطيك هذا مؤشر ترابط جديد محلي مع القيمة الأولية إلى "InclicationValue" عند الاتصال أولا Localattribute.get (). يمكنك بعد ذلك الاتصال Localattribute.set () لتعيين قيمة مختلفة. سيكون لكل مؤشر ترابط طالب قيم مختلفة لنفس السمة.

الشيء الجميل حول استخدام ThreadLocal هو أنه عند وفاة مؤشر الترابط، يجب أن تسمح مؤشر الترابط المحلي ببياناتك بأن تكون متاحة لجمع القمامة.

نصائح أخرى

هل فكرت في ThreadLocal?

أنت تحدد مساحة متغيرة "مؤشر ترابط" لمدة استدعاء Servlet واحد. أفضل طريقة هنا هي إزالة التعيين في نفس المستوى كما قمت بإضافتها، لذلك إذا أضفت إلى الخريطة في ServletFilter أود أن أضيف finally كتلة إزالة التعيين في الطريق للخروج. نفس الشيء يحمل إضافة "دليل" في Servlet.

بدائل تواجه هذه المعلومات في ServletContext أو إضافة ذلك ك ThreadLocal ينسب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top