可以将Gson实例用作模型bean中的静态字段(重用)吗?

phi*_*kim 131 java static thread-safety 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为为每个LoginSession实例创建新的Gson实例是没用的.

但我担心的是线程安全问题.将创建大约1000多个实例/秒.

将Gson实例用作静态字段是否可以?

感谢您的任何建议/更正.

MBy*_*ByD 121

对我来说似乎很好.GSON实例中没有任何内容使其与特定实例相关LoginSession,因此它应该是静态的.

GSON实例应该是线程安全的,并且有一个关于修复的错误.

  • Datetime 不是线程安全的,这可能是原因,而不是 GSON 不是线程安全的。 (2认同)

ent*_*erd 19

核心Gson类是线程安全的.我刚刚遇到了一个与GSON有关的线程安全问题.使用自定义的时候发生的问题JsonDeserializer,并JsonSerializerDate解析和格式化.事实证明,线程安全问题是我的方法使用的是一个SimpleDateFormat非线程安全的静态实例.一旦我将静态包装SimpleDateFormat在一个ThreadLocal实例中,一切都很好.

  • 一个更好的选择可能是使用Apache commons FastDateFormat(commons-lang的一部分),它明确地是线程安全的.https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html (4认同)

Chr*_*ssy 8

根据评论,现有的单元测试并没有真正测试太多,请注意与线程安全相关的任何事情......

有一个单元测试检查线程安全:

/**
 * Tests for ensuring Gson thread-safety.
 *
 * @author Inderjeet Singh
 * @author Joel Leitch
 */
public class ConcurrencyTest extends TestCase {
  private Gson gson;
  ...
Run Code Online (Sandbox Code Playgroud)

您可能想知道这个单元测试是否足以在每个可能的机器配置上找到每个可能的问题?对此有何评论?

文档中也有这句话:

在调用Json操作时,Gson实例不维护任何状态.因此,您可以自由地为多个Json序列化和反序列化操作重用相同的对象.

  • 我会说这个单元测试严重不足以检测并发问题.首先,MyObject是一个简单的类,没有涉及复杂的集合,因此不测试列表和映射以及其他复杂对象的并发/序列化.其次,序列化每10个线程只迭代10次,这是不够的.第三,无论如何都难以测试并发故障,因为不同的硬件配置具有不同的运行时特性,因此任何测试只有在保证在所有配置上运行时才有效. (3认同)
  • 不,说它不是线程安全的,只是说这个测试甚至没有远程保证它. (3认同)