È corretto utilizzare l'istanza Gson come campo statico in un bean modello (riutilizzo)?


138

Ecco il modello che ho implementato:

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);
    }
}

Ho pensato che fosse inutile creare una nuova istanza Gson per ogni istanza di LoginSession.

Ma ciò di cui sono preoccupato sono i problemi di sicurezza del thread. Verranno creati circa 1000+ istanze / sec.

È corretto utilizzare l'istanza Gson come campo statico?

Grazie per eventuali consigli / correzioni.

Risposte:


133

Mi sembra giusto. Non c'è nulla nell'istanza GSON che la renda correlata a un'istanza specifica di LoginSession, quindi dovrebbe essere statica.

Le istanze GSON dovrebbero essere thread-safe e c'era un bug riguardo a ciò che era stato corretto.


@slott, come potete raggruppare / riutilizzare le istanze di Gson? Ne crei un'istanza ogni volta che devi serializzare? O utilizzare un pool threadlocal?
Dilum Ranatunga,

Usiamo GSON insieme a Google Volley e quando analizziamo i dati JSON contemporaneamente vediamo questo problema. Da quello che posso vedere questo è legato al fatto che definiamo un timestamp per l'analisi dei valori di datetime.
slott

1
Datetime non è thread-safe, che può essere la causa, non che GSON non è thread-safe.
Andreas Mattisson,

20

La Gsonclasse principale è thread-safe. Ho appena riscontrato un problema di sicurezza del thread che si presumeva fosse con GSON. Il problema si è verificato durante l'utilizzo di un'abitudine JsonDeserializere JsonSerializerper l' Dateanalisi e la formattazione. Come si è scoperto, il problema di sicurezza del thread era con l'uso del mio metodo di SimpleDateFormatun'istanza statica che non è thread-safe. Una volta avvolta la statica SimpleDateFormatin ThreadLocalun'istanza, tutto ha funzionato bene.


4
Un'opzione migliore potrebbe essere quella di utilizzare FastDateFormat comuni di Apache (parte di commons-lang), che è esplicitamente thread-safe. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau,

Grazie @Zaan. Ottimo consiglio!
entpnerd,

8

Secondo i commenti, il test unitario esistente non verifica molto, fai attenzione a tutto ciò che riguarda la sicurezza della filettatura ...

Esiste un test unitario che verifica la sicurezza del filo:

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

Potresti chiederti se questo test unitario è sufficiente per trovare ogni possibile problema su ogni possibile configurazione della macchina? Qualche commento su questo?

C'è anche questa frase nei documenti :

L'istanza Gson non mantiene alcuno stato durante il richiamo delle operazioni Json. Quindi, sei libero di riutilizzare lo stesso oggetto per più operazioni di serializzazione e deserializzazione Json.


3
Avrei detto che questo test unitario era dolorosamente inadeguato per rilevare problemi di concorrenza. Innanzitutto, MyObject è una classe banale senza raccolte complesse, quindi la de / serializzazione simultanea di elenchi e mappe e altri oggetti complessi non viene testata. In secondo luogo, la serializzazione viene ripetuta solo 10 volte per ciascuno dei 10 thread, il che è inadeguato. In terzo luogo, i guasti di concorrenza sono notoriamente difficili da testare comunque perché configurazioni hardware diverse hanno caratteristiche di runtime diverse, quindi qualsiasi test sarebbe valido solo se garantito per essere eseguito su tutte le configurazioni.
Lawrence Dol,

1
Ad esempio, questo test probabilmente non troverà alcun errore di concorrenza su un singolo computer core, poiché ogni thread verrà probabilmente completato in un singolo intervallo di tempo e pertanto i thread verranno eseguiti consecutivamente, non contemporaneamente.
Lawrence Dol,

3
No, per dire che non è sicuro per i thread, solo che questo test non lo garantisce nemmeno da remoto.
Lawrence Dol,

1

Abbiamo avuto problemi con la sicurezza dei thread qualche tempo fa e l'abbiamo risolto utilizzando FastDateFormat nei comuni di apache.

Ho appena creato un collegamento per Gist per aiutare le persone che si chiedono se le istanze Gson possano essere riutilizzate. Non hanno setter e tutti i vars sono privati.

Quindi, a parte il problema SimpleDateFormat, non li vedo mantenere lo stato altrove.

Fare il check it out. Questa è la prima volta che rispondo a uno di questi. Felice di restituire per una volta. :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.