3

我在我的 Servlet 中使用了很多 SimpleDateFormat 对象。不幸的是,SimpleDateFormat 不是线程安全的。因此,我考虑用 ThreadLocal 包装它以促进 SimpleDateFormat 对象的重用。我写了一个 util-class 来启用它:

public class DateUtil {
    private final static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>() {
        return new SimpleDateFormat();
    }

    public static SimpleDateFormat get () {
        return dateFormat.get();
    }
}

实际上,这似乎会导致内存泄漏。关闭我的 webapp 时,Tomcat 会记录以下错误消息:

严重:Web 应用程序 [] 创建了一个 ThreadLocal,其键类型为 [null](值 [com.example.util.DateUtil$2@50242f7d]),值类型为 [java.text.SimpleDateFormat](值 [java.text .SimpleDateFormat@d91b489b]) 但在 Web 应用程序停止时未能将其删除。这很可能造成内存泄漏。

我了解内存泄漏的原因,但是在 Servlet 中处理 SimpleDateFormat 对象(或任何其他非线程安全对象)的最佳方法是什么?

4

2 回答 2

5

除了使用替代实现(commons-langjodaSimpleDateFormat )之外,只需在每次使用它时创建一个新实例。

我知道这会让你觉得很脏,需要洗澡,但这很简单,不需要你做任何努力。缺点是您将比以前交出更多的内存,但在大多数普通的 Web 应用程序中,您不太可能注意到 JDBC 的噪音。

查看我对ThreadLocal Resource Leak 和 WeakReference的回答

于 2011-01-10T22:25:49.947 回答
3

创建本地对象或使用来自 commons-lang 的FastDateFormat(FastDateFormat 是 SimpleDateFormat 的快速且线程安全的版本。)。joda-time 是所有与日期相关的问题的常见答案;-)

于 2011-01-10T22:05:54.720 回答