简体   繁体   中英

How should I declare GSON to deserialize the JSON String?

I am using Java Callable Future in my code. Below is my main code which uses the future and callables -

Below is my main code which uses the future and 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();
    }
}

Below is my Task class which implements the Callable interface in which I am making a REST URL call to my SERVERS using RestTemplate . And then deserialize the JSON String using GSON .

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);
    }
}

So my question is how should I declare GSON here? Should it be declared as static global variable in Task class? Bcoz currently I am parsing JSON using gson and for every call I am making new Gson() which would be expensive?

The source code of Gson class is here: https://code.google.com/p/google-gson/source/browse/trunk/gson/src/main/java/com/google/gson/Gson.java

It has only final fields, thus it's internal state is immutable. All referenced collections are wrapped as synchronizedMap or unmodifiableList . The toJson and fromJson methods relies primarily on local variables. So it will be safe to share the same instance.

As alfasin said, this is perfectly fine when you don't have any problems in memory. If you declared it as public static , then you need to make it synchronized since you are working in parallel threads. GC will take care once the new instance created in every call is unreachable . Since, GSON uses final member variables, you can declare it as public static Gson gson = new Gson(); and then you need to synchronize the method call for safety fromJson(response, TestResponse.class) alone like

Declare a private static final Object lock = new Object(); in Class level and use it for doing the synchronization.

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

I'm not completely sure about but, if each method call has its own call stack, there will not be any need for synchronization of this method call since each routine will have it's own variables safe.

Update: As i understood from the link , Gson is thread safe. The references are not preserved between calls. The stacks are held per calls. So, you can make the calls just like that without any synchronization

Hope, it helps you to understand!

Gson is thread-safe and would be safe to use it as a static instance in your Task class. However, if you're not having heap or performance issues it's probably fine to leave it as it is, with an Object per call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM