コードで Java Callable Future を使用しています。以下は、フューチャーと呼び出し可能オブジェクトを使用する私のメイン コードです。
public class TimeoutThread {
public static void main(String[] args) throws Exception {
// starting the background thread
new ScheduledCall().startScheduleTask();
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
以下はTask
Callable インターフェースを実装する私のクラスで、このクラスはClientData
クラスメソッドからデータを取得する必要があります。ClientData
また、セッターを使用してクラスにデータを設定するバックグラウンド スレッドがあります。
class Task implements Callable<String> {
public String call() throws Exception {
//.. some code
String hostname = ClientData.getPrimaryMapping("some_string").get(some_number);
//.. some code
}
}
ClientData
以下は、URL からのデータを解析してクラスに値を設定するバックグラウンド スレッドで、 10 分ごとに実行されます。
public class ScheduledCall {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void startScheduleTask() {
final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(
new Runnable() {
public void run() {
try {
callServers();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}, 0, 10, TimeUnit.MINUTES);
}
private void callServers() {
String url = "url";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
parseResponse(response);
}
// parse the response and set it.
private void parseResponse(String response) {
//...
ConcurrentHashMap<String, Map<Integer, String>> primaryTables = null;
//...
// store the data in ClientData class variables which can be
// used by other threads
ClientData.setPrimaryMapping(primaryTables);
}
}
そして以下は私のClientData
クラス です
public class ClientData {
private static final AtomicReference<Map<String, Map<Integer, String>>> primaryMapping = new AtomicReference<>();
public static Map<String, Map<Integer, String>> getPrimaryMapping() {
return primaryMapping.get();
}
public static void setPrimaryMapping(Map<String, Map<Integer, String>> map) {
primaryMapping.set(map);
}
}
問題文:-
私が直面している唯一の問題は、プログラムを初めて起動するときはいつでも、URL からのデータを解析するバックグラウンド スレッドを開始することです。同時に、それは私のクラスcall
のメソッドに入ります。Task
そして、以下の行は例外をスローします。なぜですか? bcoz 私のバックグラウンド スレッドはまだデータを解析しており、その変数を設定していません。
String hostname = ClientData.getPrimaryMapping("some_string").get(some_number);
この問題を回避するにはどうすればよいですか? これを行うためのより良い効率的な方法はありますか?