Czy można używać instancji Gson jako pola statycznego w fasoli modelu (ponowne użycie)?

138

Oto model, który zaimplementowałem:

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

Uważam, że tworzenie nowej instancji Gson dla każdej instancji LoginSession jest bezcelowe.

Ale martwię się o kwestie bezpieczeństwa nici. Zostanie utworzonych około 1000+ instancji / s.

Czy można używać instancji Gson jako pola statycznego?

Dzięki za wszelkie porady / poprawki.

philipjkim
źródło

Odpowiedzi:

133

Wydaje mi się to w porządku. W instancji GSON nie ma niczego, co wiązałoby ją z konkretną instancją programu LoginSession, więc powinna być statyczna.

Instancje GSON powinny być bezpieczne dla wątków i wystąpił błąd dotyczący tego, który został naprawiony.

MByD
źródło
@slott, w jaki sposób łączysz / ponownie wykorzystujesz instancje Gson? Czy tworzysz instancję za każdym razem, gdy potrzebujesz serializacji? Lub użyj puli wątkowej?
Dilum Ranatunga
Używamy GSON razem z Google Volley i kiedy równolegle parsujemy dane JSON, widzimy ten problem. Z tego, co widzę, wiąże się to z faktem, że definiujemy znacznik czasu do analizowania wartości datetime.
slott
1
Datetime nie jest bezpieczne dla wątków, co może być przyczyną, a nie to, że GSON nie jest bezpieczny dla wątków.
Andreas Mattisson
20

GsonKlasa podstawowa jest bezpieczna wątkowo. Właśnie napotkałem problem z bezpieczeństwem wątków, który podobno był związany z GSON. Wystąpił problem podczas korzystania z pliku niestandardowegoJsonDeserializer oraz JsonSerializerdo Dateanalizowania i formatowania. Jak się okazało, problem z bezpieczeństwem wątków był związany z używaniem przez moją metodę SimpleDateFormatinstancji statycznej, która nie jest bezpieczna dla wątków. Po umieszczeniu statycznej SimpleDateFormatw ThreadLocalinstancji wszystko poszło dobrze.

entpnerd
źródło
4
Lepszym rozwiązaniem może być użycie Apache commons FastDateFormat (część commons-lang), który jest jawnie bezpieczny dla wątków. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau
Dzięki @Zaan. Świetna wskazówka!
entpnerd
8

Zgodnie z komentarzami, istniejący test jednostkowy tak naprawdę nie testuje zbyt wiele, bądź ostrożny z czymkolwiek związanym z bezpieczeństwem wątków ...

Istnieje test jednostkowy sprawdzający bezpieczeństwo wątków:

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

Możesz się zastanawiać, czy ten test jednostkowy wystarczy, aby znaleźć każdy możliwy problem na każdej możliwej konfiguracji maszyny? Jakieś uwagi na ten temat?

Jest też to zdanie w docs :

Instancja Gson nie zachowuje żadnego stanu podczas wywoływania operacji Json. Możesz więc ponownie użyć tego samego obiektu do wielu operacji serializacji i deserializacji Json.

Christophe Roussy
źródło
3
Powiedziałbym, że ten test jednostkowy był żałośnie niewystarczający do wykrycia problemów ze współbieżnością. Po pierwsze, MyObject jest trywialną klasą bez skomplikowanych kolekcji, więc współbieżna de / serializacja list i map oraz inne złożone obiekty nie są testowane. Po drugie, serializacja jest powtarzana tylko 10 razy na każdy z 10 wątków, co jest niewystarczające. Po trzecie, błędy współbieżności są i tak bardzo trudne do przetestowania, ponieważ różne konfiguracje sprzętowe mają różne charakterystyki środowiska wykonawczego, więc każdy test byłby ważny tylko wtedy, gdy gwarantuje się, że zostanie uruchomiony we wszystkich konfiguracjach.
Lawrence Dol
1
Na przykład ten test prawdopodobnie nie znajdzie żadnego błędu współbieżności na maszynie z jednym rdzeniem, ponieważ każdy wątek prawdopodobnie zakończy się w ciągu jednego krotności czasu, a zatem wątki będą działać kolejno, a nie współbieżnie.
Lawrence Dol
3
Nie, żeby powiedzieć, że nie jest bezpieczne dla wątków, tyle że ten test nawet nie gwarantuje, że tak jest.
Lawrence Dol
1

Jakiś czas temu mieliśmy problemy z bezpieczeństwem wątków i rozwiązaliśmy je za pomocą FastDateFormat w apache commons.

Właśnie stworzyłem link do Gist wokół tego, aby pomóc ludziom zastanawiać się, czy instancje Gson można ponownie wykorzystać. Nie mają seterów i wszystkie zmienne są prywatne.

Więc poza problemem SimpleDateFormat nie widzę, aby utrzymywały stan nigdzie indziej.

Sprawdź to . Odpowiadam na jedno z nich po raz pierwszy. Chętnie oddam choć raz. :)

aarengee
źródło