Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I declare GSON to deserialize the JSON String?

Tags:

java

gson

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?

like image 999
AKIWEB Avatar asked Jan 24 '14 04:01

AKIWEB


3 Answers

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.

like image 184
Alexander Tokarev Avatar answered Oct 19 '22 15:10

Alexander Tokarev


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.

like image 43
Durandal Avatar answered Oct 19 '22 16:10

Durandal


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!

like image 22
Keerthivasan Avatar answered Oct 19 '22 15:10

Keerthivasan