Apakah boleh menggunakan instance Gson sebagai bidang statis dalam model bean (reuse)?

143

Inilah model yang saya terapkan:

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

Saya pikir tidak ada gunanya membuat instance Gson baru untuk setiap instance LoginSession.

Tapi yang saya khawatirkan adalah masalah keamanan benang. Sekitar 1000+ instance / detik akan dibuat.

Apakah tidak masalah menggunakan instance Gson sebagai bidang statis?

Terima kasih atas saran / koreksi apapun.

philipjkim.dll
sumber

Jawaban:

136

Sepertinya baik-baik saja bagiku. Tidak ada dalam instance GSON yang membuatnya terkait dengan instance tertentu LoginSession, jadi harus statis.

Instans GSON harus aman untuk thread , dan ada bug terkait yang telah diperbaiki.

MByD
sumber
@slott, bagaimana kalian mengumpulkan / menggunakan kembali instance Gson? Apakah Anda membuat contoh setiap kali Anda perlu membuat serial? Atau gunakan kumpulan threadlocal?
Dilum Ranatunga
Kami menggunakan GSON bersama-sama dengan Google Volley dan saat kami mengurai data JSON secara bersamaan, kami melihat masalah ini. Dari apa yang saya lihat ini terkait dengan fakta bahwa kita mendefinisikan stempel waktu untuk mengurai nilai-nilai waktu.
slott
1
Datetime tidak aman untuk thread, itu bisa menjadi penyebabnya, bukan karena GSON tidak aman untuk thread.
Andreas Mattisson
21

Kelas inti Gsonaman untuk thread. Saya baru saja mengalami masalah keamanan utas yang seharusnya terjadi pada GSON. Masalahnya terjadi saat menggunakan kustom JsonDeserializerdan JsonSerializeruntuk Datepenguraian dan pemformatan. Ternyata, masalah keamanan thread adalah penggunaan metode saya atas SimpleDateFormatinstance statis yang tidak aman untuk thread. Setelah saya membungkus statis SimpleDateFormatdalam sebuah ThreadLocalcontoh, semuanya bekerja dengan baik.

entpnerd
sumber
4
Pilihan yang lebih baik adalah menggunakan FastDateFormat Apache commons (bagian dari commons-lang), yang secara eksplisit threadsafe. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau
Terima kasih @Zaan. Tip yang bagus!
entpnerd
8

Menurut komentar pengujian unit yang ada tidak terlalu banyak menguji, berhati-hatilah dengan apa pun yang berkaitan dengan keamanan utas ...

Ada tes unit yang memeriksa keamanan benang:

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

Anda mungkin bertanya-tanya apakah pengujian unit ini cukup untuk menemukan setiap kemungkinan masalah pada setiap konfigurasi mesin yang memungkinkan? Ada komentar tentang ini?

Ada juga kalimat ini di dokumen :

Instance Gson tidak mempertahankan status apa pun saat menjalankan operasi Json. Jadi, Anda bebas menggunakan kembali objek yang sama untuk beberapa operasi serialisasi dan deserialisasi Json.

Christophe Roussy
sumber
3
Saya akan mengatakan pengujian unit ini sangat tidak memadai untuk mendeteksi masalah konkurensi. Pertama, MyObject adalah kelas sepele tanpa koleksi kompleks yang terlibat sehingga deretan daftar dan peta dan objek kompleks lainnya tidak diuji secara bersamaan. Kedua, serialisasi hanya diulang 10 kali per masing-masing dari 10 utas, yang tidak memadai. Ketiga, kesalahan konkurensi sangat sulit untuk diuji karena konfigurasi perangkat keras yang berbeda memiliki karakteristik waktu proses yang berbeda, sehingga pengujian apa pun hanya akan valid jika dijamin untuk dijalankan pada semua konfigurasi.
Lawrence Dol
1
Misalnya, pengujian ini kemungkinan tidak akan menemukan kesalahan konkurensi apa pun pada mesin inti tunggal, karena setiap utas mungkin akan selesai dalam satu kutu waktu dan karena itu utas akan berjalan secara berurutan, bukan secara bersamaan.
Lawrence Dol
3
Tidak untuk mengatakan itu bukan threadsafe, hanya saja tes ini bahkan tidak menjaminnya dari jarak jauh.
Lawrence Dol
1

Kami memiliki masalah dengan keamanan utas beberapa waktu lalu dan kami menyelesaikannya dengan menggunakan FastDateFormat di apache commons.

Baru saja membuat Tautan inti untuk Gist seputar ini untuk membantu orang-orang yang bertanya-tanya apakah instance Gson dapat digunakan kembali. Mereka tidak memiliki setter dan semua vars bersifat pribadi.

Jadi selain masalah SimpleDateFormat, saya tidak melihat mereka mempertahankan status di tempat lain.

Apakah memeriksa itu keluar. Ini adalah pertama kalinya saya membalas salah satu dari ini. Senang memberi kembali untuk sekali. :)

aarengee
sumber