É possível usar a instância do Gson como um campo estático em um bean de modelo (reutilização)?

138

Aqui está o modelo que eu implementei:

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

Eu pensei que era inútil criar uma nova instância do Gson para cada instância do LoginSession.

Mas o que me preocupa são os problemas de segurança de threads. Aproximadamente 1000 instâncias / s serão criadas.

Posso usar a instância do Gson como campo estático?

Obrigado por quaisquer conselhos / correções.

philipjkim
fonte

Respostas:

133

Parece bom para mim. Não há nada na instância do GSON que o relacione a uma instância específica de LoginSession, portanto deve ser estático.

As instâncias do GSON devem ser seguras para threads , e houve um erro em relação ao que foi corrigido.

MByD
fonte
@ Slott, como vocês agrupam / reutilizam instâncias do Gson? Você instancia um sempre que precisa serializar? Ou usar um pool local de threads?
Dilum Ranatunga 29/10
Usamos o GSON junto com o Google Volley e, quando analisamos os dados JSON simultaneamente, vemos esse problema. Pelo que posso ver, isso está relacionado ao fato de definirmos um carimbo de data / hora para analisar valores de data e hora.
slott
1
O tempo de data não é seguro para threads, pode ser a causa, não que o GSON não seja seguro para threads.
Andreas Mattisson
20

A Gsonclasse principal é segura para threads. Acabei de encontrar um problema de segurança de segmento que supostamente estava com o GSON. O problema ocorreu ao usar um costume JsonDeserializere JsonSerializerpara Dateanalisar e formatar. Como se viu, o problema de segurança do thread estava no uso do meu método de uma SimpleDateFormatinstância estática que não é segura para threads. Depois que envolvi a estática SimpleDateFormatem um ThreadLocalexemplo, tudo deu certo.

entpnerd
fonte
4
Uma opção melhor pode ser usar o FastDateFormat do Apache commons (parte do commons-lang), que é explicitamente seguro para threads. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau
Obrigado @Zaan. Ótima dica!
entpnerd
8

De acordo com os comentários, o teste de unidade existente realmente não testa muito, tenha cuidado com qualquer coisa relacionada à segurança da linha ...

Há um teste de unidade que verifica a segurança da linha:

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

Você pode se perguntar se esse teste de unidade é suficiente para encontrar todos os problemas possíveis em todas as configurações possíveis da máquina? Algum comentário sobre isso?

Há também esta frase nos documentos :

A instância Gson não mantém nenhum estado ao invocar operações Json. Portanto, você pode reutilizar o mesmo objeto para várias operações de serialização e desserialização do Json.

Christophe Roussy
fonte
3
Eu diria que esse teste de unidade foi lamentavelmente inadequado para detectar problemas de simultaneidade. Primeiro, o MyObject é uma classe trivial sem coleções complexas envolvidas, de modo que a des / serialização simultânea de listas e mapas e outros objetos complexos não sejam testados. Segundo, a serialização é iterada apenas 10 vezes por cada um dos 10 threads, o que é inadequado. Terceiro, as falhas de simultaneidade são notoriamente difíceis de serem testadas, porque configurações diferentes de hardware têm características de tempo de execução diferentes; portanto, qualquer teste só seria válido se fosse garantido que fosse executado em todas as configurações.
Lawrence Dol
1
Por exemplo, esse teste provavelmente não encontrará nenhuma falha de simultaneidade em uma máquina de núcleo único, pois cada thread provavelmente será concluído em uma única divisão de tempo e, portanto, os threads serão executados consecutivamente, não simultaneamente.
Lawrence Dol
3
Não é necessário dizer que não é seguro para threads, apenas que esse teste nem garante remotamente que é.
Lawrence Dol
1

Há algum tempo, tivemos problemas com a segurança do encadeamento e resolvemos usando o FastDateFormat no apache commons.

Apenas criei um link gist para Gist em torno disso para ajudar as pessoas que se perguntam se as instâncias do Gson podem ser reutilizadas. Eles não têm setters e todos os vars são particulares.

Portanto, além do problema SimpleDateFormat, não os vejo mantendo o estado em nenhum outro lugar.

Verifique isso . É a primeira vez que respondo a uma delas. Feliz em retribuir pela primeira vez. :)

aarengee
fonte