java中清理/删除未使用的地图元素的策略

发布于 2024-08-10 04:45:20 字数 1738 浏览 15 评论 0原文

我正在我的网络应用程序中实现一个“管理器”,可以调用它来设置和获取当前线程所在的网站上下文(我们对我们的网站进行白色标记,以便网站上下文代表我们所在的网站)

我'我正在尝试找出执行此操作的最佳策略,目前我正在并发哈希映射中实现将线程存储到 WebSiteContext:

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

在线程的开头(通过 Servlet Filter 或通过手动设置它)线程将关联到其 WebSiteContext,

但希望清理 Map 以避免内存泄漏。所以我想一种策略是迭代映射的 Thread 键以查明线程是否“活动”(thread.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);
               }
            }
      }
   }

但是我想这需要我同步对地图的访问(或者确实如此?)这是我想避免的。

是否有任何“惯用”模式用于在 java 中的线程中存储属性或确实清理以 Thread 对象作为键的映射?我愿意使用 Wea​​kReference / SoftReferences 或者实际上如果有 Thread.getCurrentThread().setAttribute(Object, Object) 的等效项,那就太好了

干杯 西蒙·B

I'm implementing a "manager" in my web app that can be called to set and get which web site context the current thread is in (we white label our site so the web site context represents which site we're on)

I'm trying to work out what the best strategy to do this, currently I'm implementing the store of Threads to WebSiteContexts in a concurrent hash map:

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

at the beginning of the thread (either through a Servlet Filter or through manually setting it) the thread will be associated to its WebSiteContext,

but want to clean up the Map to avoid a memory leak. So I guess one strategy is to iterate through the Thread keys of the map to find out whether the threads are "alive" (thread.isAlive()) and if not remove it for example like this:

 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);
               }
            }
      }
   }

, but this I guess requires me to synchronize access to the map (or does it?) which is something I want to avoid.

Is there any "idiomatic" pattern for storing attributes in threads in java or indeed cleaning up maps that have Thread objects as keys? I'm open to using WeakReference / SoftReferences or indeed if there is some equivalent of Thread.getCurrentThread().setAttribute(Object, Object), that would be great

Cheers
Simon B

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

明月夜 2024-08-17 04:45:20

你有没有想过ThreadLocal

Have you thought about ThreadLocal?

蓦然回首 2024-08-17 04:45:20

你的方法可能有效,但你最终会做比需要的更多的工作。 ThreadLocal 是您正在寻找的。这将允许您存储与应用程序中每个线程相关的对象。使用它的典型方法是实现initialValue() 方法,该方法为其分配第一个值。示例:

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

当您第一次调用 localAttribute.get() 时,这将为您提供一个新的本地线程,其初始值为“InitialValue”。然后您可以调用 localAttribute.set() 为其分配不同的值。每个请求者线程对于同一属性将具有不同的值。

使用 ThreadLocal 的好处是,当线程终止时,线程本地应该允许您的数据可用于垃圾回收。

Your approach may work but you would end up doing more work than neeeded. ThreadLocal is what you are looking for. This will allow you to store objects related to each thread in your application. The typical way to use it is to implement the initialValue() method which assigns it the first value. Example:

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

This will give you a new thread local with the initial value to "InitialValue" when you first call localAttribute.get(). You can then call localAttribute.set() to assign it a different value. Each requester thread will have different values for the same attribute.

The nice thing about using ThreadLocal is that when the thread dies, the thread local should allow your data to be available for garbage collection.

何时共饮酒 2024-08-17 04:45:20
盗梦空间 2024-08-17 04:45:20

您正在为一个 Servlet 调用的持续时间定义一个“线程本地”变量空间。这里最好的方法是在添加映射的同一级别删除映射,因此,如果您在 ServletFilter 中添加映射,我会添加一个 finally 块,该块已删除出路时的地图。这同样适用于 Servlet 中的“手动”添加。

替代方案是在您的 ServletContext 中包含此信息,或者将其添加为 ThreadLocal 属性。

You are defining a "thread local" variable space for the duration of one servlet call. The best way here is to remove the mapping at the same level as you added it, so if you add to the map in a ServletFilter I would add a finally block that removed the mapping on the way out. The same holds for a "manual" addition in a servlet.

Alternatives are having this information in your ServletContext or adding it as a ThreadLocal attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文