Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Использование Future.get (timeout) из ExecutorService должно обрабатывать это довольно чисто.
Например:
ExecutorService executor = Executors.newCachedThreadPool();
// ... set up builder as before ...
Future<Response> responseFuture = executor.submit(
() -> builder.post(Entity.json(new Gson().toJson(request))));
try {
Response response = responseFuture.get(timeout, TimeUnit.SECONDS);
// return normal response here
} catch (TimeoutException ex) {
executor.submit( () -> {
Response lateResponse = responseFuture.get();
// send overThreshold alert email here
// Dummy return - prefer Callable to Runnable here for exception handling
return null;
} );
// return a message to user here saying their payment could not be processed
}
Выбор ExecutorService
можно настроить так, чтобы он соответствовал или равным образом был общим пулом потоков в других местах приложения.
Можно использовать CompletableFuture
с ExecutorService
(как отмечалось ранее), который немного более изящен. Вот пример,
ExecutorService executor = Executors.newCachedThreadPool();
CompletableFuture<Response> future = CompletableFuture.supplyAsync(() ->
builder.post(Entity.json(new Gson().toJson(request))), executor);
Response response = null;
try {
response = future.get(timeout, TimeUnit.SECONDS);
} catch (Exception e) {
log.debug("Encountered error while calling payment processor", e);
}
Согласно Javadoc, get
, метод ожидает при необходимости в течение самое большее данного времени для этого будущего для завершения и затем возвращает свой результат при наличии.