¿Está bien usar la instancia de Gson como un campo estático en un bean modelo (reutilizar)?

138

Aquí está el modelo que implementé:

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

Pensé que era inútil crear una nueva instancia de Gson para cada instancia de LoginSession.

Pero lo que me preocupa son los problemas de seguridad de los hilos. Se crearán aproximadamente más de 1000 instancias / seg.

¿Está bien usar la instancia de Gson como campo estático?

Gracias por cualquier consejo / corrección.

philipjkim
fuente

Respuestas:

133

Me parece bien. No hay nada en la instancia de GSON que lo relacione con una instancia específica de LoginSession, por lo que debe ser estático.

Las instancias de GSON deben ser seguras para subprocesos , y hubo un error con respecto a lo que se corrigió.

MByD
fuente
@slott, ¿cómo agrupan / reutilizan las instancias de Gson? ¿Crea una instancia cada vez que necesita serializar? ¿O usar un grupo de hilos locales?
Dilum Ranatunga
Usamos GSON junto con Google Volley y cuando analizamos datos JSON concurrentes vemos este problema. Por lo que puedo ver, esto está relacionado con el hecho de que definimos una marca de tiempo para analizar los valores de fecha y hora.
slott
1
Datetime no es seguro para subprocesos, esa puede ser la causa, no es que GSON no sea seguro para subprocesos.
Andreas Mattisson el
20

La Gsonclase principal es segura para subprocesos. Acabo de encontrar un problema de seguridad de hilos que supuestamente estaba relacionado con GSON. El problema ocurrió cuando se usaba una costumbre JsonDeserializery JsonSerializerpara Dateanalizar y formatear. Al final resultó que, el problema de seguridad de subprocesos fue con el uso de mi método de una SimpleDateFormatinstancia estática que no es segura para subprocesos. Una vez que envolví la estática SimpleDateFormaten una ThreadLocalinstancia, todo salió bien.

entpnerd
fuente
44
Una mejor opción puede ser usar Apache commons FastDateFormat (parte de commons-lang), que es explícitamente seguro para subprocesos. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau
Gracias @Zaan. Gran consejo!
entpnerd
8

De acuerdo con los comentarios, la prueba de la unidad existente realmente no prueba mucho, tenga cuidado con cualquier cosa relacionada con la seguridad del hilo ...

Hay una prueba de unidad que verifica la seguridad del hilo:

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

¿Se preguntará si esta prueba de unidad es suficiente para encontrar todos los problemas posibles en cada configuración de máquina posible? ¿Algún comentario sobre esto?

También hay esta oración en los documentos :

La instancia de Gson no mantiene ningún estado al invocar operaciones de Json. Por lo tanto, puede reutilizar el mismo objeto para múltiples operaciones de serialización y deserialización de Json.

Christophe Roussy
fuente
3
Hubiera dicho que esta prueba unitaria era lamentablemente inadecuada para detectar problemas de concurrencia. Primero, MyObject es una clase trivial sin colecciones complejas involucradas, por lo que no se prueba la deserialización / serialización simultánea de listas y mapas y otros objetos complejos. En segundo lugar, la serialización solo se repite 10 veces por cada uno de los 10 subprocesos, lo cual es inadecuado. Tercero, las fallas de concurrencia son notoriamente difíciles de probar de todos modos porque las diferentes configuraciones de hardware tienen diferentes características de tiempo de ejecución, por lo que cualquier prueba solo sería válida si se garantiza que se ejecute en todas las configuraciones.
Lawrence Dol
1
Por ejemplo, es probable que esta prueba no encuentre ningún fallo de concurrencia en una sola máquina central, ya que cada subproceso probablemente se completará dentro de un único segmento de tiempo y, por lo tanto, los subprocesos se ejecutarán consecutivamente, no concurrentemente.
Lawrence Dol
3
No es para decir que no es seguro para subprocesos, solo que esta prueba ni siquiera garantiza remotamente que lo sea.
Lawrence Dol
1

Tuvimos problemas con la seguridad de subprocesos hace un tiempo y lo resolvimos usando FastDateFormat en apache commons.

Acabo de crear un enlace Gist para Gist en torno a esto para ayudar a las personas a preguntarse si las instancias de Gson pueden reutilizarse. No tienen setters y todos los vars son privados.

Entonces, aparte del problema SimpleDateFormat, no veo que mantengan el estado en ningún otro lugar.

Mira esto . Esta es la primera vez que respondo a uno de estos. Feliz de devolver por una vez. :)

aarengee
fuente