You can do through a stream
in parallel. But for this, it is first necessary to "hide" the exception to a RuntimeException
(read more).
Let’s put a TEN 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 inner part of your loop into a method that doesn’t throw exception checked, that turns them 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 method findAll
return a Collection
(as a List
), we can transform that bond for
in 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), make these calls through parallelStream
uses as many cores as possible for processing, but does not create threads
beyond what can actually be consumed.
On the other hand, this is not the case, as you reminded me. However, almost nothing is lost. It has a great article by Baeldung on the subject. He resolves it 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;
}
You have to have a pool of connections with the bank, ie each thread will have to separately make your call to the bank and do the search, since each connection supports only one object (the call). As for the threads, search for
ExecutorService
, which is an API core Java to handle a pool of threads asynchronously. Take a look atCompletableFuture
also, which is for the asynchronous return of your method (your search) to be stored and manipulated.– StatelessDev
@Statelessdev, for the threaded part, I think it’s best to use
parallelStream
. This avoids you, as a programmer, having to deal explicitly with parallelism, when this particular parallelism has every way of being totally non-compete. Seems like a typical scenario I just have to wait forjoins
threads– Jefferson Quesado