Frage

Ich habe ein statisches Objekt in meiner Logging-Klasse definiert, entlang der Linien von:

   class myLoggingClass {
     static java.util.Properties properties;
     ...
     ...
   }

Nach meinem Nachschlagewerk, bedeutet dies, dass die Eigenschaften Objekt von allen Instanzen meiner Klasse geteilt wird.

Ich finde diese Definition nicht ausreichend. Ich bin eine Klasse zu schreiben, die mehr als einmal in jeder Anwendung auf unserem Projekt aufgerufen wird.

Ferner unser Projekt verwendet mehr Web-Dienste im gleichen Tomcat-Container ausgeführt wird. Jeder Web-Service kann mehrere Threads haben.

Die Java Virtual Machine auf dem Host ausgeführt kann auch eine oder mehrere Web-Service-Client-Anwendungen laufen, die tomcat auf externe ausgeführt werden.

So nach dieser Definition kann ich tomcat mehrere Web-Dienste mit Fäden laufen, die jeweils mehrere Objekte, die eine Instanz meiner Klasse enthalten.

Es gibt auch ein oder zwei Web-Clients sein kann, außerhalb von tomcat ausgeführt wird, aber innerhalb der gleichen JVM. Würde alle diese Instanzen meiner Klasse Anteil Objekt der gleichen Eigenschaften? Dies würde es JVM weit.

Wenn das statische Objekt ist nicht JVM-breit, weiß jemand, auf welcher Ebene jeder existieren würde? Eine pro tomcat Container? Ein pro Web-Service und ein pro Standalone-Web-Service-Client-Anwendung?

Der Grund: Wenn ich meine Eigenschaften aktualisieren, ich bin ein java.lang.ConcurrentUpdateException von java.util.Properties bekommen.

Ich verwende eine statische boolsche Variable „sperren“, die Objekteigenschaften, wenn meine Klasse Updates, aber dies ist nicht die Ausnahme von dem Auftreten zu halten.

Dies führt mich, dass das statische Objekt in meiner Klasse verwendet, zu glauben, kann nicht als ein in java.util.Properties verwendete bei der gleichen Scoping-Ebene sein ... Aber das ist nur eine Vermutung.

Vielen Dank für jede Hilfe.

War es hilfreich?

Lösung

Die wahrscheinliche Ursache Ihrer ConcurrentModificationException ist, dass Sie in einem Thread durch die Werte / Einträge der Properties Objekt iterieren, während ein anderer sie zugleich verändert. Sie können dies nicht tun.

Können Sie auf den Verriegelungsmechanismus auszuarbeiten, die Sie hier erwähnen:

  

Ich verwende eine statische boolsche Variable „sperren“, die Objekteigenschaften, wenn meine Klasse Updates, aber nicht die Ausnahme hält auftritt.

Weil es klingt nicht, als ob Sie mit dem eingebauten in Schließ- und Synchronisationsmethoden in Java.

So etwas sollte Fäden verhindern, dass das Lesen der Eigenschaften-Objekt während eines anderen Thread aktualisiert sie:

static Object lockObject = new Object();

...

synchronized(lockObject) {
     // access the Properties object
}

Beachten Sie, dass Sie das tun müssen, um alle Wenn Sie diese Eigenschaften Objekt zugreifen, entweder zu lesen oder modifizieren.

Auch ich würde nie statische Objekte empfehlen Daten von allen Instanzen oder statischen lockObjects zu teilen - globale Daten sind schlecht - aber es klingt, als ob Sie dies aus irgendeinem Grunde benötigen

.

Andere Tipps

Statiken sind nicht „von allen Instanzen einer Klasse geteilt“ - sie sind nicht verwandt zu Instanzen; Sie gehören zu den geben sich . Insbesondere sind statische Variablen perfekt geeignet, ohne jeder Instanzen erstellt werden.

Das gibt einen Hinweis auf den Umfang der Statik: sie vom Class Objekt scoped ist die enthaltenden Klasse darstellt, die wiederum von den ClassLoader scoped, die es geladen

.

Je nachdem, wo die Bibliothek platziert wird, kann die statische Variable sein JVM weit oder Web-Anwendung breit -. Oder möglicherweise etwas dazwischen, wenn Tomcat mehr Hosting unterstützt (ich ohne Weiteres nicht mehr erinnern kann)

Sehen Sie in der Tomcat-Dokumentation, wie die Bibliotheken angelegt und wie sie sich auf Klassenlader beziehen. Zum Beispiel ist hier die Tomcat 6.0 Classloader-Leitfaden herunter und das Äquivalent für 5,5 .

Wie sieht Ihr Boolean „sperren“ arbeiten? Sie sollten wirklich ein richtiges Schloss (synchronized) verwenden, um sicherzustellen, dass jede Nutzung der Eigenschaften Objekt (sowohl lesen als auch schreiben, auch für den gesamten Zeitraum Sperren während der Sie durchlaufen) wird in geeigneter Weise verriegelt.

Statt die „live“ Properties Objekt zu ändern, haben Sie darüber nachgedacht Behandlung, dass als unveränderlich - so, wenn Sie die Eigenschaften aktualisieren möchten, können Sie eine Kopie nehmen, ändern, und dann die Kopie der „Live“ -Version machen? Sie würden immer noch zwei verschiedene Threads verhindern, müssen Änderungen in der gleichen Zeit von zu machen (oder würden Sie einige verlieren), aber es ist wahrscheinlich, dass die Leseseite viel einfacher und effizienter zu gestalten.

machen

Sie können feststellen, dass der Umfang eines solchen static Variable auf einen pro Classloader begrenzt ist, die Klasse geladen ist. Ich bin mir nicht sicher, wie Tomcat seine Classloader arrangiert, so ist es schwer zu sagen, was das Ausmaß des Umfangs in dieser Umgebung sein wird.

Könnte es ein Problem sein, wenn Classloader das Glas, die Ihre Klasse enthält in jedem WEB-INF / lib Ihrer verschiedenen Anwendungen dupliziert? Wenn ja, würde ich versuchen, dieses Glas zu Tomcat Libs hinzuzufügen und nicht auf die Anwendung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top