You can do this through stream
in parallel. But for this, it is first necessary to "hide" the exception for a RuntimeException
( read more ).
Let's go through a RTE that loads UnknownHostException
or IOException
, to use it within the lambda expression:
class WrapperException extends RuntimeException {
final UnknownHostException uhe;
final IOException ioe;
WrapperException(UnknownHostException uhe) {
super(uhe);
this.uhe = uhe;
this.ioe = null;
}
WrapperException(IOException ioe) {
super(ioe);
this.uhe = null;
this.ioe = ioe;
}
void throwWrappedException() throws UnknownHostException, IOException {
if (this.uhe != null) throw uhe;
if (this.ioe != null) throw ioe;
}
}
Now, let's turn the inside of your loop into a method that does not throw an exception checked, transforming it into WrapperException
:
void setStatusMonitoriaEntidade(MonitoriaEntidade monitoriaEntidade) {
try {
if (InetAddress.getByName(monitoriaEntidade.getIp()).isReachable(5000)) {
monitoriaEntidade.setStatus(true);
}
} catch (IOException e) {
throw new WrapperException(e);
} catch (UnknownHostException e) {
throw new WrapperException(e);
}
}
So if hypothetically the
findAll
method returns a
Collection
(as a
List
), we can turn that loop
for
into a
parallelStream
:
@GetMapping
public List<MonitoriaEntidade> resposta() throws UnknownHostException, IOException {
List<MonitoriaEntidade> findAll = monitoriaRepositorio.findAll();
try {
findAll.parallelStream().forEach(this::setStatusMonitoriaEntidade);
} catch (WrapperException e) {
// se um dos processamentos der ruim, lança a exceção; mesmo comportamento anterior
e.throwWrappedException();
}
return findAll;
}
In my experiments (I did not find the official documentation on the subject), making these calls through parallelStream
uses the maximum number of cores available for processing, but does not create threads
beyond what can actually be consumed. / p>
On the other hand, this is not the case, as you reminded me. However, almost nothing is lost. You have a great Baeldung article on the subject. It fixes this using StreamSupport
:
@GetMapping
public Iterable<MonitoriaEntidade> resposta() throws UnknownHostException, IOException {
Iterable<MonitoriaEntidade> findAll = monitoriaRepositorio.findAll();
try {
StreamSupport.stream(findAll.spliterator(), true).forEach(this::setStatusMonitoriaEntidade);
} catch (WrapperException e) {
// se um dos processamentos der ruim, lança a exceção; mesmo comportamento anterior
e.throwWrappedException();
}
return findAll;
}