我在我的代码中使用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()
都会很昂贵吗?
答案 0 :(得分:5)
Gson
类的源代码在这里:https://code.google.com/p/google-gson/source/browse/trunk/gson/src/main/java/com/google/gson/Gson.java
它只有final
个字段,因此它的内部状态是不可变的。所有引用的集合都包装为synchronizedMap
或unmodifiableList
。 toJson
和fromJson
方法主要依赖于局部变量。因此,共享同一个实例是安全的。
答案 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
。