Я догадываюсь о коде, который вы не показывали, но если это Callable , который вы вызываете с ExecutorService , любое исключение, которое происходит внутри кода Callable не будет никуда распространяться, пока вы не вызовете один из методов get () для Future , который был возвращен, когда вы отправили Callable . Когда вы вызываете get (), он генерирует исключение ExecutionException, основной причиной которого является исключение, выброшенное из вашего кода.
Проще говоря, когда вы разветвляете код в другой поток с помощью ExecutorService, любое исключение, генерируемое из этого кода, перехватывается и удерживается до тех пор, пока вы не вернетесь и не спросите результат выполнения кода. Если вы этого не сделаете, исключение просто исчезнет.