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以及解析和格式化JsonSerializer时会出现此问题。Date事实证明,线程安全问题在于我的方法使用了SimpleDateFormat非线程安全的静态实例。一旦我将静态包装SimpleDateFormat在一个ThreadLocal实例中,一切都很好。

于 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

不久前我们遇到了线程安全问题,我们通过在 apache commons 中使用 FastDateFormat 解决了这个问题。

刚刚为 Gist 创建了一个 gist 链接,以帮助人们想知道是否可以重用 Gson 实例。他们没有设置器,所有变量都是私有的。

因此,除了 SimpleDateFormat 问题之外,我看不到它们在其他任何地方保持状态。

一定要检查一下。这是我第一次回复其中一个。乐于回馈一次。:)

于 2020-04-21T08:53:19.320 回答