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.

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.


@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.


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.


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. :)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.