2012-04-30 17 views
103

ここで私は実装モデルがあります:Model BeanでGsonインスタンスを静的フィールドとして使用することはできますか(再利用)?

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インスタンスを静的フィールドとして使用しても問題ありませんか?

アドバイス/訂正ありがとうございます。

答えて

90

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

GSONインスタンスshould be thread-safeであり、固定されたbug regardingがありました。

+7

GSONの同時性問題のため、クラッシュしました。だから私はそれが100%スレッドセーフではないと思っています。 – slott

+0

@slott、あなたはGsonインスタンスをどのようにプール/再利用しますか?シリアル化する必要があるたびにインスタンス化しますか?または、スレッドローカルプールを使用しますか? –

+0

GSONとGoogle Volleyを併用しており、JSONデータを同時に解析するときにこの問題が発生します。私が見ることができるのは、datetime値を解析するためのタイムスタンプを定義するという事実に関連しています。 – slott

8

のコメントによると、既存のユニットテストは本当に多くのテストをしない、安全性をスレッド化に関連するものには注意してください...

スレッドの安全性をチェックするunit testがあります:

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

あなたはこの単体テストですべての可能な機械構成で起こりうるあらゆる問題を発見するのに十分であるのだろうか?これに関するコメント?

この文はdocsでもあります:

JSON オペレーションの呼び出し中Gsonインスタンスがどのような状態を維持しません。したがって、複数の同じオブジェクトを自由に再利用することができます。 Jsonのシリアル化とデシリアライズ操作。

+2

私は、この単体テストが並行性の問題を検出するのに悲惨なほど不十分だと言ったでしょう。まず、MyObjectは、複雑なコレクションが含まれていない簡単なクラスなので、リストとマップの同時直列化やその他の複雑なオブジェクトはテストされません。第2に、直列化は10個のスレッドごとに10回しか反復されないが、これは不十分である。第3に、異なるハードウェア構成で実行時の特性が異なるため、並行性障害はテストするのが難しいことが知られているため、すべての構成で実行することが保証されている場合のみ有効です。 –

+0

たとえば、このテストでは、単一のコアマシンで同時実行フォルトが検出されない可能性があります。なぜなら、各スレッドはおそらく単一のタイムスライス内で完了するため、スレッドは同時に実行されるのではなく連続して実行されるからです。 –

+1

スレッドセーフではないことは言うまでもありませんが、このテストではそれが遠隔的に保証されることさえありません。 –

10

コアGsonクラスはスレッドセーフです。 GSONと思われるスレッドセーフの問題が発生しました。この問題は、とJsonSerializerを使用して、Dateの解析と書式設定を行ったときに発生しました。スレッドセーフの問題は、私のメソッドでスレッドセーフではないスタティックSimpleDateFormatインスタンスを使用していたことが判明しました。一度私はのインスタンスに静的なSimpleDateFormatをラップすると、すべてうまくいきました。

+2

より良い選択肢は、明示的にスレッドセーフであるApacheコモンズFastDateFormat(commons-langの一部)を使用することです。 https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html – Zaan

+0

ありがとう@ザーン。素晴らしいヒント! – entpnerd

関連する問題