2012-04-30 2 views
103

Hier ist das Modell, das ich implementiert:Ist es in Ordnung, die Gson-Instanz als statisches Feld in einer Modell-Bean zu verwenden (Wiederverwendung)?

public class LoginSession { 
    private static final Gson gson = new Gson(); 

    private String id; 
    private String name; 
    private long timestamp; 

    public LoginSession(String id, String name) { 
     this.id = id; 
     this.name = name; 
     this.timestamp = System.currentTimeMillis(); 
    } 

    public String toJson() { 
     return gson.toJson(this); 
    } 

    public static LoginSession fromJson(String json) { 
     checkArgument(!isNullOrEmpty(json)); 
     return gson.fromJson(json, LoginSession.class); 
    } 
} 

Ich dachte, es ist nutzlos für jede LoginSession Instanz neue Gson Instanz zu erstellen.

Aber worüber ich besorgt bin, sind Thread-Sicherheitsprobleme. Ungefähr 1000 Instanzen/Sek. Werden erstellt.

Ist es in Ordnung, Gson-Instanz als statisches Feld zu verwenden?

Vielen Dank für irgendwelche Hinweise/Korrekturen.

Antwort

90

Es scheint mir gut. Es gibt nichts in der GSON-Instanz, das es mit einer bestimmten Instanz von LoginSession verknüpft, daher sollte es statisch sein.

GSON-Instanzen should be thread-safe, und es gab eine bug regarding, die behoben wurde.

+7

Wir hatten gerade einen Absturz wegen Nebenläufigkeit Probleme mit GSON. Ich denke also nicht, dass es 100% threadsicher ist - zumindest nicht, wenn man nachJson ruft. – slott

+0

@slott, wie gepoolt/wiederverwendet Gson Instanzen? Instanziieren Sie jedes Mal, wenn Sie serialisieren müssen, eines davon? Oder verwende einen threadlocal Pool? –

+0

Wir verwenden GSON zusammen mit Google Volley und wenn wir JSON-Daten gleichzeitig analysieren, sehen wir dieses Problem. Was ich sehen kann, hängt damit zusammen, dass wir einen Zeitstempel für das Parsen von Datetime-Werten definieren. – slott

8

Nach den Kommentaren der bestehenden Unit-Test nicht wirklich viel testet, seien Sie vorsichtig mit etwas Sicherheit fädeln im Zusammenhang ...

Es gibt einen unit test für Thread-Sicherheit überprüft:

/** 
* Tests for ensuring Gson thread-safety. 
* 
* @author Inderjeet Singh 
* @author Joel Leitch 
*/ 
public class ConcurrencyTest extends TestCase { 
    private Gson gson; 
    ... 

Sie Ich frage mich, ob dieser Komponententest ausreicht, um jedes mögliche Problem bei jeder möglichen Maschinenkonfiguration zu finden. Irgendwelche Kommentare dazu?

Es gibt auch diesen Satz in den docs:

Die Gson Instanz hält keinen Zustand, während Json Aufruf Operationen. Sie können also das gleiche Objekt für mehrere JSSSerialisierungs- und Deserialisierungsvorgänge wiederverwenden.

+2

Ich hätte gesagt, dass dieser Komponententest völlig unzureichend ist, um Nebenläufigkeitsprobleme zu erkennen. Erstens ist das MyObject eine triviale Klasse ohne komplexe Sammlungen, so dass die gleichzeitige De-/Serialisierung von Listen und Karten und anderen komplexen Objekten nicht getestet wird. Zweitens wird die Serialisierung nur 10 Mal pro 10 Threads wiederholt, was nicht ausreichend ist.Drittens sind Nebenläufigkeitsfehler bekanntermaßen ohnehin schwierig zu testen, da unterschiedliche Hardwarekonfigurationen unterschiedliche Laufzeiteigenschaften aufweisen, so dass jeder Test nur dann gültig wäre, wenn er garantiert für alle Konfigurationen ausgeführt wird. –

+0

Zum Beispiel wird dieser Test wahrscheinlich keinen Nebenläufigkeitsfehler auf einer Single-Core-Maschine finden, da jeder Thread wahrscheinlich innerhalb eines einzigen Zeitfensters abgeschlossen wird und die Threads daher fortlaufend und nicht gleichzeitig ausgeführt werden. –

+1

Nein zu sagen, es ist nicht Thread sicher, nur dass dieser Test nicht einmal im Entferntesten garantiert, dass es ist. –

10

Die Klasse Gson ist Thread-sicher. Ich bin gerade auf ein Problem mit der Thread-Sicherheit gestoßen, das angeblich bei GSON aufgetreten ist. Das Problem trat bei der Verwendung einer benutzerdefinierten JsonDeserializer und JsonSerializer für Date Analyse und Formatierung auf. Wie sich herausstellte, bestand das Problem der Thread-Sicherheit darin, dass meine Methode eine statische SimpleDateFormat Instanz verwendete, die nicht Thread-sicher ist. Sobald ich die statische SimpleDateFormat in eine ThreadLocal Instanz gewickelt habe, hat alles gut geklappt.

+2

Eine bessere Option könnte sein, Apache commons FastDateFormat (Teil von commons-lang) zu verwenden, was explizit threadsafe ist. https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html – Zaan

+0

Danke @Zaan. Toller Tipp! – entpnerd

Verwandte Themen