If the program has several different interactions with threads, it makes sense to center and encapsulate this functionality in a specialized class.
On the name, I would avoid anything named "global" and in this case exposing implementation details.
A priori, I would model this class first by defining interfaces for the manager running the program functions and for the commands. Example:
interface Comando {
void executar();
}
interface GerenciadorExecucao {
void executar(Comando c);
}
Note that the interfaces do not say how the commands will be executed. Such detail will be managed by the implementation and the other classes have nothing to do with it, for them this is transparent, they just expect the command to be executed.
As for the implementation, I would create a class called GerenciadorExecucaoAssincrono
containing a thread pool whose threads consume the commands of a synchronized queue as LinkedBlockingQueue
. Example;
class GerenciadorExecucaoAssincrono implements GerenciadorExecucao {
private final int maximumPoolSize = 4;
private final ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Orders-%d").setDaemon(true).build();
private final ExecutorService executorService = Executors.newFixedThreadPool(maximumPoolSize, threadFactory);
private final LinkedBlockingQueue<Comando> queue = new LinkedBlockingQueue<>()
public GerenciadorExecucaoAssincrono() {
//thread que fica em loop infinito consumindo os comandos da fila
executorService.submit(() -> {
while(true) {
Comando c = queue.take(); //espera por um comando na fila
c.executar();
}
});
}
public void executar(Comando c) {
//adiciona o comando à fila, desbloqueando a thread acima
queue.put(c);
}
}
You can now create any command implementation in other classes. This way, every feature of your system can use the new asynchronous and uncoupled execution API.
In the above example, I created a single thread consuming the commands, so the result is that the commands are executed in the same order they are added to the queue.
However, you can have multiple threads and run them in parallel, just submit several times the same Runnable
I put in the lambda above. The problem with this is that the commands executed at the same time could have an unwanted effect, since you have physical equipment and possible limitations. It’s up to you to analyze this and think about the best strategy.
Thank you very much for the answer. I understood your placement perfectly, really this way I can leave the commands uncoupled. Some equipment use
TCP/IP
others useSerial
for communication, by several factors, that way I could not use them in parallel, because I would only have an equal exit door. I will still have to think of something as a priority for these commands, but this is for a next question, after I try to implement some logic for this. Thanks again.– Paulo H. Hartmann