我应该如何声明GSON反序列化JSON字符串?

时间:2014-01-24 04:55:32

标签: java gson

我在我的代码中使用Java Callable Future。下面是我使用未来和callables的主要代码 -

下面是我使用未来和callables的主要代码 -

public class TimeoutThread {

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);
        Future<String> future = executor.submit(new Task());

        try {
            System.out.println(future.get(3, TimeUnit.SECONDS));
        } catch (TimeoutException e) {

        }

        executor.shutdownNow();
    }
}

下面是我的Task类,它实现了Callable接口,我在其中使用RestTemplate对我的SERVERS进行REST URL调用。然后使用GSON反序列化JSON字符串。

class Task implements Callable<String> {
    private static RestTemplate restTemplate = new RestTemplate();

    @Override
    public String call() throws Exception {

    String url = "some_url";            
    String response = restTemplate.getForObject(url, String.class);

    TestResponse jsonResponse = new Gson().fromJson(response, TestResponse.class);
    }
}

所以我的问题是我应该如何在这里声明GSON?它应该在Task类中声明为静态全局变量吗? Bcoz目前我正在使用gson解析JSON,并且我正在进行的每次调用new Gson()都会很昂贵吗?

3 个答案:

答案 0 :(得分:5)

Gson类的源代码在这里:https://code.google.com/p/google-gson/source/browse/trunk/gson/src/main/java/com/google/gson/Gson.java

它只有final个字段,因此它的内部状态是不可变的。所有引用的集合都包装为synchronizedMapunmodifiableListtoJsonfromJson方法主要依赖于局部变量。因此,共享同一个实例是安全的。

答案 1 :(得分:1)

正如alfasin所说,当你在记忆中没有任何问题时,这是完全正常的。如果您将其声明为public static,则需要将其设为synchronized,因为您正在使用并行线程。一旦在每个呼叫中​​创建的新实例无法访问, GC将会非常小心。由于GSON使用最终成员变量,您可以将其声明为public static Gson gson = new Gson();,然后您需要单独同步安全性fromJson(response, TestResponse.class)的方法调用,如

在Class级别声明private static final Object lock = new Object();并使用它进行同步。

//explicit locking
synchronized(lock){
//do the method call here
gson.fromJson(response, TestResponse.class);
}

我不完全确定,但是,如果每个方法调用都有自己的调用堆栈,则不需要同步此方法调用,因为每个例程都有自己的变量安全。

更新: 正如我从link所理解的那样,Gson是线程安全的。调用之间不保留引用。每次调用都会保留堆栈。因此,您可以在没有任何同步的情况下进行调用

希望,它可以帮助你理解!

答案 2 :(得分:1)

Gson是thread-safe,可以安全地将其用作static课程中的Task个实例。但是,如果您没有堆或性能问题,可以保持原样,每次调用Object