Ist es in Ordnung, die Gson-Instanz als statisches Feld in einer Modell-Bean zu verwenden (Wiederverwendung)?

138

Hier ist das Modell, das ich implementiert habe:

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 fand es sinnlos, für jede LoginSession-Instanz eine neue Gson-Instanz zu erstellen.

Was mich jedoch beunruhigt, sind Fragen der Thread-Sicherheit. Es werden ungefähr 1000+ Instanzen / Sek. Erstellt.

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

Vielen Dank für Ratschläge / Korrekturen.

philipjkim
quelle

Antworten:

133

Es scheint mir in Ordnung zu sein. In der GSON-Instanz gibt es nichts, was sie auf eine bestimmte Instanz von bezieht LoginSession, daher sollte sie statisch sein.

GSON-Instanzen sollten threadsicher sein , und es gab einen Fehler in Bezug auf das , was behoben wurde.

MByD
quelle
@slott, wie bündelt / wiederverwendet ihr Gson-Instanzen? Instanziieren Sie jedes Mal eine, wenn Sie serialisieren müssen? Oder einen threadlokalen Pool verwenden?
Dilum Ranatunga
Wir verwenden GSON zusammen mit Google Volley und wenn wir JSON-Daten gleichzeitig analysieren, sehen wir dieses Problem. Soweit ich sehen kann, hängt dies damit zusammen, dass wir einen Zeitstempel zum Parsen von Datums- / Uhrzeitwerten definieren.
Slott
1
Datetime ist nicht threadsicher, das kann die Ursache sein, nicht, dass GSON nicht threadsicher ist.
Andreas Mattisson
20

Die Kernklasse Gsonist threadsicher. Ich bin gerade auf ein Thread-Sicherheitsproblem gestoßen, das angeblich mit GSON zusammenhängt. Das Problem trat bei der Verwendung einer benutzerdefinierten Funktion JsonDeserializersowie JsonSerializerbeim DateParsen und Formatieren auf. Wie sich herausstellte, bestand das Thread-Sicherheitsproblem darin, dass meine Methode eine statische SimpleDateFormatInstanz verwendete, die nicht threadsicher ist. Nachdem ich die Statik SimpleDateFormatin eine ThreadLocalInstanz eingewickelt hatte , funktionierte alles einwandfrei.

entpnerd
quelle
4
Eine bessere Option ist möglicherweise die Verwendung von Apache Commons FastDateFormat (Teil von commons-lang), das explizit threadsicher ist. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau
Danke @Zaan. Toller Tipp!
Entpnerd
8

Laut den Kommentaren testet der bestehende Unit-Test nicht wirklich viel, seien Sie vorsichtig mit allem, was mit Thread-Sicherheit zu tun hat ...

Es gibt einen Unit-Test zur Überprüfung der Gewindesicherheit:

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

Sie fragen sich vielleicht, 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 Dokumenten :

Die Gson-Instanz behält beim Aufrufen von Json-Vorgängen keinen Status bei. Sie können also dasselbe Objekt für mehrere Json-Serialisierungs- und Deserialisierungsvorgänge wiederverwenden.

Christophe Roussy
quelle
3
Ich hätte gesagt, dass dieser Komponententest absolut unzureichend war, um Parallelitätsprobleme zu erkennen. Erstens ist das MyObject eine triviale Klasse ohne komplexe Sammlungen, sodass die gleichzeitige De- / Serialisierung von Listen und Karten sowie anderen komplexen Objekten nicht getestet wird. Zweitens wird die Serialisierung nur 10 Mal pro 10 Threads wiederholt, was nicht ausreichend ist. Drittens sind Parallelitätsfehler ohnehin notorisch schwer zu testen, da unterschiedliche Hardwarekonfigurationen unterschiedliche Laufzeitmerkmale aufweisen. Daher wäre jeder Test nur gültig, wenn garantiert wird, dass er auf allen Konfigurationen ausgeführt wird.
Lawrence Dol
1
Beispielsweise wird bei diesem Test wahrscheinlich kein Parallelitätsfehler auf einem einzelnen Kerncomputer festgestellt, da jeder Thread wahrscheinlich innerhalb einer einzelnen Zeitscheibe abgeschlossen wird und die Threads daher nicht gleichzeitig, sondern nacheinander ausgeführt werden.
Lawrence Dol
3
Nein zu sagen, es ist nicht threadsicher, nur dass dieser Test nicht einmal aus der Ferne garantiert, dass dies der Fall ist.
Lawrence Dol
1

Wir hatten vor einiger Zeit Probleme mit der Thread-Sicherheit und haben sie durch die Verwendung von FastDateFormat in Apache Commons gelöst.

Ich habe gerade einen Link für Gist erstellt, um den Leuten zu helfen, sich zu fragen, ob Gson-Instanzen wiederverwendet werden können. Sie haben keine Setter und alle Vars sind privat.

Abgesehen vom SimpleDateFormat-Problem sehe ich nirgendwo anders einen Status.

Probieren Sie es aus. Ich antworte zum ersten Mal auf eine dieser Fragen. Gerne einmal zurückgeben. :) :)

aarengee
quelle