Frage

Mein begrenztes Verständnis von Thread dass sie Ressource Leck Probleme . Ich nehme dieses Problem kann durch die richtige Verwendung von behoben werden WeakReferences mit Thread (obwohl ich diesen Punkt falsch verstanden haben könnte.) ich möchte einfach ein Muster oder Beispiel für richtig Thread mit WeakReference verwenden, falls vorhanden. Zum Beispiel in diesem Codefragment, wo würde der WeakReference eingeführt werden?

static class DateTimeFormatter {
    private static final ThreadLocal<SimpleDateFormat> DATE_PARSER_THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy/MM/dd HH:mmz");
        }
    };
    public String format(final Date date) {
        return DATE_PARSER_THREAD_LOCAL.get().format(date);
    }
    public Date parse(final String date) throws ParseException
    {
      return DATE_PARSER_THREAD_LOCAL.get().parse(date);
    }
}
War es hilfreich?

Lösung

ThreadLocal verwendet eine WeakReference intern. Wenn die ThreadLocal nicht stark referenziert wird, wird es Garbage Collection, auch wenn verschiedene Threads Werte über diesen ThreadLocal gespeichert haben.

Zusätzlich ThreadLocal Werte werden in der Thread tatsächlich gespeichert sind; wenn ein Thread stirbt, sind alle Werte mit diesem Thread durch einen ThreadLocal zugeordnet gesammelt.

Wenn Sie eine ThreadLocal als letzte Klasse Mitglied haben, das ist ein starker Hinweis, und es kann nicht gesammelt werden, bis die Klasse entladen wird. Aber das ist, wie jede Klasse Mitglied arbeitet, und ist nicht ein Speicherverlust betrachtet.


Update:. Das zitierte Problem kommt nur ins Spiel, wenn die in einem ThreadLocal gespeicherten Wert stark, dass ThreadLocal-Art eines Kreis Referenz verweist

In diesem Fall wird der Wert (a SimpleDateFormat) hat Referenz nicht rückwärts in den ThreadLocal. Es gibt keinen Speicherverlust in diesem Code.

Andere Tipps

Ich vermute, Sie durch diese Reifen sind springen, da Simple ist nicht Thread-sicher .

Während ich bin mir bewusst, ich bin zu lösen Ihr Problem nicht oben, kann ich schlage vor, Sie schauen unter Joda für Ihre Zeit / Datum Arbeit? Joda einen Gewinde-safe Formatierungsmechanismus Datum / Uhrzeit. Sie werden die Joda API Lernen entweder nicht Ihre Zeit verschwenden, da sie die Grundlage für den neuen Standard Datum / Zeit-API Vorschlag ist.

Es nicht sein, ein Problem dar.

Ein Threadreferenz Thread definiert nur so lange existieren, wie der entsprechende Thread am Leben (siehe javadoc) ist - oder anders gesagt, wenn der Faden nicht am Leben ist, wenn der Thread der einzige Verweis auf dieses Objekt ist, dann das Objekt für die Garbage collection in Anspruch genommen werden.

Also entweder haben Sie einen echten Fehler gefunden und ist zu berichten, oder Sie tun etwas anderes falsch!

Ich weiß, dies nicht unbedingt eine Antwort auf Ihre Frage ist aber in der Regel werde ich nicht vorschlagen, ein ThreadLocal in situration mit, wo es keine klare Träne nach unten am Ende einer Anfrage / Interaktion ist. Die klassische tut diese Art der Sache in einem Servlet-Container, auf den ersten Blick in Ordnung scheint, aber da die Fäden vereinigt werden, wird es ein Problem mit der ThreadLocal auf die Ressource hängt auch nach jeder Anfrage bearbeitet wurde.

Vorschläge:

  1. einen Filter ähnlichen Wrapper für jede Interaktion Mit dem Thread am Ende jeder Interaktion löschen
  2. Sie können eine Alternative nutzen könnten, um zu Simple wie FastDateFormat von commons-lang oder Joda als jemand bereits vorgeschlagen hat,
  3. Erstellen Sie einfach eine neue Simple jedes Mal wenn Sie es brauchen. Scheine verschwenderisch ich weiß, aber in den meisten Anwendungen, die Sie einfach nicht den Unterschied bemerken

Just hinzuzufügen auf das, was @Neil Coffey sagte, ist dies kein Problem, solange Ihr Thread Instanz statisch sein sollte. Weil Sie rief get halten () auf einer statische Instanz, es sollte immer den gleichen Bezug auf Ihre einfachen Datumsformatierer halten. Daher ist, wie Neil sagte, wenn der Thread beendet wird, soll die einzige Instanz von einfachen Datumsformatierer für die Garbage Collection in Betracht.

Wenn Sie Zahlen oder eine andere Form von Debugging haben, dass diese Einführung Ressourcenprobleme zeigt, dann ist das eine andere Geschichte. Aber ich glaube, wie es sollte kein Problem sein.

In Ihrem Beispiel soll es überhaupt kein Problem mit einem Thread sein.

Thread Einheimischen (und Singletons auch!) Zu einem Problem werden, wenn Thread Einheimischen Instanzen festgelegt werden durch einen Klassenlader geladen später entladen werden. Eine typische Situation in einem Servlet-Container (wie tomcat):

  1. A webapp Satz einen lokalen Thread während der Anforderungsverarbeitung.
  2. Der Faden durch den Behälter geleitet wird.
  3. Die Webapp nicht entfalteten werden sollen.
  4. Die Klassenlader der Webapp können nicht garbaged werden, denn es ist eine Referenz. Links: aus dem lokalen Thread zu der Instanz seiner Klasse auf sein Klassenladeprogramm

Das gleiche mit Singletons (java.sql.DriverManger und JDBC-Treiber von der Webapp angeboten).

So solche Dinge insbesondere vermeiden in Umgebungen nicht unter dem vollen Kontrolle!

Reinigen Sie den lokalen Thread nach der Benutzung, Servlet-Filter hinzufügen, dies zu tun:

protected ThreadLocal myThreadLocal = new ThreadLocal();

public void doFilter (ServletRequest req, ServletResponse res, chain) throws IOException, ServletException {
    try {
        // Set ThreadLocal (eg. to store heavy computation result done only once per request)
        myThreadLocal.set(context());

        chain.doFilter(req, res);
    } finally {
        // Important : cleanup ThreaLocal to prevent memory leak
        userIsSmartTL.remove();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top