web-dev-qa-db-ja.com

GsonインスタンスをモデルBeanの静的フィールドとして使用しても問題ありませんか(再利用)?

私が実装したモデルは次のとおりです。

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

LoginSessionインスタンスごとに新しいGsonインスタンスを作成するのは無意味だと思いました。

しかし、私が心配しているのは、スレッドセーフの問題です。約1000インスタンス/秒が作成されます。

Gsonインスタンスを静的フィールドとして使用しても大丈夫ですか?

アドバイス/修正をありがとう。

129
philipjkim

私にはそれでいいようです。 GSONインスタンスには、LoginSessionの特定のインスタンスに関連するものがないため、静的である必要があります。

GSONインスタンス スレッドセーフである必要があります 、および修正された バグに関する がありました。

119
MByD

コアGsonクラスはスレッドセーフです。おそらくGSONにあったスレッドセーフの問題に遭遇しました。この問題は、カスタムJsonDeserializerおよびJsonSerializerDate解析およびフォーマットに使用しているときに発生しました。判明したように、スレッドセーフの問題は、スレッドセーフではない静的SimpleDateFormatインスタンスを私のメソッドが使用することにありました。静的なSimpleDateFormatThreadLocalインスタンスにラップすると、すべてうまくいきました。

19
entpnerd

コメントによると、既存の単体テストではあまりテストされていません。スレッドセーフティに関連するものには注意してください...

ユニットテスト スレッドの安全性をチェックしています:

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

この単体テストは、考えられるすべてのマシン構成で考えられるすべての問題を見つけるのに十分かどうか疑問に思うかもしれません。これについて何かコメントはありますか?

docs にも次の文があります。

Gsonインスタンスは、Json操作の呼び出し中に状態を維持しません。そのため、同じオブジェクトを複数のJsonシリアル化および逆シリアル化操作に自由に再利用できます。

8