2012-04-30 9 views
103

Oto model I wdrożone:Czy można używać instancji Gson jako pola statycznego w komponencie bean modelu (ponowne użycie)?

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

myślałem, że to nie ma sensu, aby utworzyć nową instancję Gson dla każdej instancji LoginSession.

Ale martwię się problemami związanymi z bezpieczeństwem wątków. Zostanie utworzonych około 1000+ wystąpień/sekundę.

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

Dzięki za wszelkie porady/korekty.

Odpowiedz

90

Wydaje mi się, że to w porządku. W instancji GSON nie ma nic, co powodowałoby, że byłby powiązany z konkretnym wystąpieniem LoginSession, więc powinien być statyczny.

Instancje GSON should be thread-safe, i nie było bug regarding, który został naprawiony.

+7

Po prostu mieliśmy awarię z powodu problemów z współbieżnością z GSON. Więc nie sądzę, że jest w 100% bezpieczny dla wątków - przynajmniej nie dzwonię do Json. – slott

+0

@slott, jak ludzie gromadzą/wykorzystują instancje Gson? Czy tworzysz instancję za każdym razem, gdy potrzebujesz serializacji? Lub użyć puli wątkowej? –

+0

Używamy GSON razem z Google Volley, a kiedy analizujemy 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

8

Według komentarzach istniejących testów jednostkowych naprawdę nie testują wiele, być ostrożnym z czymkolwiek związanym z wątku bezpieczeństwa ...

Jest unit test sprawdzanie bezpieczeństwa wątku:

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

Ty może zastanawiać się, czy ten test jednostkowy wystarczy, aby znaleźć każdy możliwy problem w każdej możliwej konfiguracji maszyny? Wszelkie komentarze na ten temat?

Istnieje również to zdanie w docs:

Instancja Gson nie utrzymuje żadnego stanu podczas wywoływania JSON operacje. Tak więc, możesz ponownie użyć tego samego obiektu dla wielu operacji szeregowania i deserializacji Json.

+2

Powiedziałbym, że ten test jednostkowy był żałośnie niewystarczający do wykrycia problemów z współbieżnością. Po pierwsze, obiekt MyObject jest klasą trywialną bez złożonych kolekcji, więc równoległe de/serializacja list i map oraz innych złożonych obiektów nie jest testowane. Po drugie, serializacja jest powtarzana 10 razy na każdy z 10 wątków, co jest niewystarczające.Po trzecie, awarie współbieżności są bardzo trudne do przetestowania, ponieważ różne konfiguracje sprzętowe mają różne charakterystyki runtime, więc każdy test byłby ważny tylko wtedy, gdy gwarantowane jest uruchamianie we wszystkich konfiguracjach. –

+0

Na przykład ten test prawdopodobnie nie wykryje żadnego błędu współbieżności na maszynie z pojedynczym rdzeniem, ponieważ każdy wątek prawdopodobnie zakończy się w ciągu pojedynczego przedziału czasowego, a wątki będą zatem następowały kolejno, a nie jednocześnie. –

+1

Nie można powiedzieć, że nie jest to bezpieczne dla wątków, ale tylko ten test nawet nie gwarantuje, że tak jest. –

10

Klasa rdzenia Gson jest wątkowo bezpieczna. Właśnie napotkałem problem z bezpieczeństwem wątków, który podobno miał miejsce w przypadku GSON. Problem wystąpił podczas korzystania z niestandardowego przetwarzania i formatowania. Jak się okazało, problem związany z bezpieczeństwem wątków wynikał z użycia przez moją metodę statycznej instancji SimpleDateFormat, która nie jest wątkowo bezpieczna. Po zapakowaniu statycznego egzemplarza SimpleDateFormat w instancji ThreadLocal wszystko działało dobrze.

+2

Lepszym rozwiązaniem może być użycie Apache commons FastDateFormat (część commons-lang), który jest jawnie bezpieczny dla wątków. https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html – Zaan

+0

Dzięki @Zaan. Świetna rada! – entpnerd