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


138

这是我实现的模型:

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实例用作静态字段吗?

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

Answers:


133

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

GSON实例应该是线程安全的,并且存在关于修复问题错误


@slott,你们如何合并/重用Gson实例?您是否需要在每次序列化时实例化一个?还是使用threadlocal池?
Dilum Ranatunga,

我们将GSON与Google Volley一起使用,当我们并行解析JSON数据时,我们会看到此问题。从我看到的情况来看,这与以下事实有关:我们定义了一个用于解析日期时间值的时间戳。
老虎机

1
日期时间不是线程安全的,这可能是原因,而不是GSON不是线程安全的。
安德烈亚斯·马蒂森

20

核心Gson类是线程安全的。我刚刚遇到了GSON可能存在的线程安全问题。使用自定义的时候发生的问题JsonDeserializer,并JsonSerializerDate解析和格式化。事实证明,线程安全问题是由于我的方法使用了一个SimpleDateFormat不是线程安全的静态实例。一旦将静态包装SimpleDateFormatThreadLocal实例中,一切工作就很好了。


4
更好的选择可能是使用显式线程安全的Apache commons FastDateFormat(commons-lang的一部分)。commons.apache.org/proper/commons-lang/apidocs/org/apache/…–
Marceau

谢谢@Zaan。大提示!
2016年

8

根据评论,现有的单元测试并不能真正进行太多测试,请谨慎对待与线程安全性相关的任何事情。

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

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

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

docs中也有这句话:

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


3
我会说这个单元测试严重不足以检测并发问题。首先,MyObject是一个琐碎的类,不涉及复杂的集合,因此不测试列表和地图以及其他复杂对象的并发反序列化。其次,每个10个线程中的每个序列化仅迭代10次,这是不够的。第三,众所周知,并发错误无论如何都很难测试,因为不同的硬件配置具有不同的运行时特性,因此,只有保证在所有配置上都可以运行,任何测试才有效。
劳伦斯·多尔

1
例如,此测试可能不会在单个核心计算机上发现任何并发错误,因为每个线程可能会在单个时间片内完成,因此这些线程将连续运行,而不是同时运行。
劳伦斯·多尔2014年

3
不用说它不是线程安全的,只是这个测试甚至不能远程保证它是线程安全的。
劳伦斯·多尔

1

不久前,我们在线程安全方面遇到了问题,我们通过在Apache Commons中使用FastDateFormat解决了该问题。

刚刚为此创建了一个gist 链接,以帮助人们怀疑Gson实例是否可以重用。他们没有二传手,所有的变量都是私有的。

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

请检查了。这是我第一次回复其中一个。乐于回馈一次。:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.