Pergunta sobre o tipo de tutorial de threading Java
-
03-07-2019 - |
Pergunta
Sou bastante ingênuo quando se trata do mundo de Java Threading e Simultaneidade.Atualmente estou tentando aprender.Fiz um exemplo simples para tentar descobrir como funciona a simultaneidade.
Aqui está o meu código:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadedService {
private ExecutorService exec;
/**
* @param delegate
* @param poolSize
*/
public ThreadedService(int poolSize) {
if (poolSize < 1) {
this.exec = Executors.newCachedThreadPool();
} else {
this.exec = Executors.newFixedThreadPool(poolSize);
}
}
public void add(final String str) {
exec.execute(new Runnable() {
public void run() {
System.out.println(str);
}
});
}
public static void main(String args[]) {
ThreadedService t = new ThreadedService(25);
for (int i = 0; i < 100; i++) {
t.add("ADD: " + i);
}
}
}
O que preciso fazer para que o código imprima os números de 0 a 99 em ordem sequencial?
Solução
Conjuntos de threads geralmente são usados para operações que não necessitam sincronização ou são altamente paralelo.
Imprimir os números de 0 a 99 sequencialmente não é um problema simultâneo e requer que os threads sejam sincronizados para evitar a impressão fora de ordem.
Recomendo dar uma olhada no Lição de simultaneidade Java para ter uma ideia de simultaneidade em Java.
Outras dicas
A idéia de threads não é fazer as coisas sequencialmente.
Você precisará de algum estado compartilhado para coordenar. No exemplo, a adição de campos de instância à sua classe externa funcionará neste exemplo. Remova o parâmetro de Add. Adicione um objeto de bloqueio e um contador. Pegue a trava, imprima o número, incremente o número, libere o número.
A solução mais simples para o seu problema é usar um tamanho de threadpool de 1. No entanto, esse não é realmente o tipo de problema que se usaria threads para resolver.
Para expandir, se você criar seu executor com:
this.exec = Executors.newSingleThreadExecutor();
Em seguida, todos os seus tópicos serão agendados e executados na ordem em que foram enviados para execução. Existem alguns cenários em que isso é uma coisa lógica a se fazer, mas na maioria dos casos os threads são a ferramenta errada a ser usada para resolver esse problema.
Esse tipo de coisa faz sentido fazer quando você precisa executar a tarefa em um tópico diferente - talvez demore muito tempo para executar e você não deseja bloquear um tópico da GUI - mas você não precisa ou não Não quer que as tarefas enviadas sejam executadas ao mesmo tempo.
O problema é por definição não adequado aos threads. Os threads são executados de forma independente e não há realmente uma maneira de prever qual encadeamento é executado primeiro.
Se você deseja alterar seu código para ser executado sequencialmente, altere adicionar a:
public void add(final String str) {
System.out.println(str);
}
Você não está usando threads (pelo menos não seus) e tudo acontece sequencialmente.