13

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<TestResponse> 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 I am passing response variable to checkString method in which I am deserializing the JSON string and then I am checking whether the key has error or warning in it and then basis on that make a TestResponse.

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

    @Override
    public TestResponse call() throws Exception {

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

    TestResponse response = checkString(response);
    }
}

private TestResponse checkString(final String response) throws Exception {

    Gson gson = new Gson(); // is this an expensive call here, making objects for each and every call?
    TestResponse testResponse = null;
    JsonObject jsonObject = gson.fromJson(response, JsonObject.class); // parse, need to check whether it is an expensive call or not.
    if (jsonObject.has("error") || jsonObject.has("warning")) {

        final String error = jsonObject.get("error") != null ? jsonObject.get("error").getAsString() : jsonObject
            .get("warning").getAsString();

        testResponse = new TestResponse(response, "NONE", "SUCCESS");
    } else {
        testResponse = new TestResponse(response, "NONE", "SUCCESS");
    }

    return testResponse;
}

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

AKIWEB
  • 19,008
  • 67
  • 180
  • 294
  • See http://stackoverflow.com/questions/10380835/is-it-ok-to-use-gson-instance-as-a-static-field-in-a-model-bean-reuse – Vadzim Mar 15 '16 at 09:48

2 Answers2

20

The Gson object is explicitly safe to use from multiple threads, as it doesn't keep any internal state, so yes, declare a private static final Gson GSON = new Gson();, or even make it public.

Note that if you want your client code to be able to customize the rendering by using GsonBuilder, you should accept a Gson object as a parameter.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • 2
    +1: Here is the official word on not maintaining any state during json operations https://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson – StoopidDonut Feb 11 '14 at 18:00
  • @chrylis: Can you explain on your second point for GsonBuilder as I haven't used it before so don't know about that. or if you can provide an example on that, then it will be of great help. – AKIWEB Feb 11 '14 at 20:09
  • @AKIWEB You can configure the JSON output from Gson. You use `GsonBuilder` to do that. Look at the docs for examples. – chrylis -cautiouslyoptimistic- Feb 11 '14 at 20:44
1

The Gson library can be defined at the class level and be used everywhere because it does not maintain state across different invocations. Since it doesn't maintain state, you can declare it once and use it everywhere (one less line of code if you need to reuse it). Multi threading will have no effect on it. On another note though, looking at it's performance metrics in it's official documentation, it doesn't seem to be an expensive call.

ucsunil
  • 7,378
  • 1
  • 27
  • 32