156

これが私が実装したモデルです:

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インスタンスを静的フィールドとして使用しても大丈夫ですか?

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

4

4 に答える 4

145

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

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

于 2012-04-30T08:51:10.723 に答える
26

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

于 2016-02-03T23:25:00.487 に答える
8

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

スレッドセーフをチェックする単体テストがあります。

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

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

ドキュメントにもこの文があります:

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

于 2014-10-13T08:36:11.233 に答える
1

しばらく前にスレッドセーフに問題があり、ApacheCommonsでFastDateFormatを使用して問題を解決しました。

Gsonインスタンスを再利用できるかどうか疑問に思っている人々を支援するために、この周りにGistの要点リンクを作成しました。セッターはなく、すべての変数はプライベートです。

したがって、SimpleDateFormatの問題を除いて、他の場所で状態を維持していることはわかりません。

ぜひチェックてください。これらのいずれかに返信するのはこれが初めてです。一度お返しします。:)

于 2020-04-21T08:53:19.320 に答える