No RxJava, existem 5 agendadores diferentes para você escolher:
imediato () : cria e retorna um agendador que executa o trabalho imediatamente no segmento atual.
trampolim () : cria e retorna um agendador que enfileira o trabalho no encadeamento atual a ser executado após a conclusão do trabalho atual.
newThread () : cria e retorna um agendador que cria um novo thread para cada unidade de trabalho.
computation () : cria e retorna um agendador destinado ao trabalho computacional. Isso pode ser usado para loops de eventos, processamento de retornos de chamada e outros trabalhos computacionais. Não execute trabalho vinculado a E / S neste planejador. Use agendadores. io () em vez disso.
io () : cria e retorna um agendador destinado ao trabalho vinculado a E / S. A implementação é apoiada por um pool de threads do Executor que aumentará conforme necessário. Isso pode ser usado para executar de forma assíncrona o bloqueio de E / S. Não execute trabalho computacional neste planejador. Use agendadores. computation () .
Questões:
Os três primeiros agendadores são bastante auto-explicativos; no entanto, estou um pouco confuso sobre computação e io .
- O que exatamente é "trabalho vinculado a IO"? É usado para lidar com fluxos (
java.io
) e arquivos (java.nio.files
)? É usado para consultas ao banco de dados? É usado para baixar arquivos ou acessar APIs REST? - Qual a diferença entre computação () e newThread () ? Será que todas as chamadas de computação () estão em um único segmento (segundo plano) em vez de um novo segmento (segundo plano) de cada vez?
- Por que é ruim chamar computation () ao fazer um trabalho de IO?
- Por que é ruim chamar io () ao fazer um trabalho computacional?
timeout
por padrãocomputation()
estaria bloqueando um thread, mas não é o caso. Sob as cobertascomputation()
usa umScheduledExecutorService
tempo para que ações atrasadas não sejam bloqueadas. Dado esse fato,computation()
é uma boa idéia, porque se estivesse em outro encadeamento, estaríamos sujeitos a custos de troca de encadeamentos.O ponto mais importante é que aputação de Schedulers.io e Schedulers.com é suportada por pools de encadeamentos ilimitados, em oposição aos outros mencionados na pergunta. Essa característica é compartilhada apenas pelos Schedulers.from (Executor) no caso em que o Executor é criado com newCachedThreadPool (ilimitado com um pool de threads de recuperação automática).
Conforme explicado em abundância nas respostas anteriores e em vários artigos na Web, aputação Schedulers.io e Schedulers.com deve ser usada com cuidado, pois são otimizados para o tipo de trabalho em seu nome. Mas, do meu ponto de vista, o papel mais importante é fornecer simultaneidade real para fluxos reativos .
Contrariamente à crença dos recém-chegados, os fluxos reativos não são inerentemente simultâneos, mas inerentemente assíncronos e seqüenciais. Por esse motivo, Schedulers.io deve ser usado apenas quando a operação de E / S estiver bloqueando (por exemplo: usando um comando de bloqueio como o Apache IOUtils FileUtils.readFileAsString (...) ) congelaria o encadeamento de chamada até que a operação seja feito.
O uso de um método assíncrono, como Java AsynchronousFileChannel (...), não bloqueia o encadeamento de chamada durante a operação, portanto, não faz sentido usar um encadeamento separado. De fato, Schedulers.io encadeamentos não são realmente adequados para operações assíncronas, pois não executam um loop de eventos e o retorno de chamada nunca ... seria chamado.
A mesma lógica se aplica ao acesso ao banco de dados ou às chamadas remotas à API. Não use o Schedulers.io se você puder usar uma API assíncrona ou reativa para fazer a chamada.
Voltar para simultaneidade. Você pode não ter acesso a uma API assíncrona ou reativa para executar operações de E / S de forma assíncrona ou simultânea, portanto, sua única alternativa é enviar várias chamadas em um encadeamento separado. Infelizmente, os fluxos reativos são seqüenciais em seus fins, mas a boa notícia é que o operador flatMap () pode introduzir simultaneidade em seu núcleo .
A simultaneidade deve ser construída na construção de fluxo, normalmente usando o operador flatMap () . Este poderoso operador pode ser configurado para fornecer internamente um contexto multithread para sua função incorporada flatMap () <T, R>. Esse contexto é fornecido por um agendador multiencadeado, como Scheduler.io ou Scheduler.computation .
Encontre mais detalhes em artigos sobre agendadores RxJava2 e Concorrência , onde você encontrará amostra de código e explicações detalhadas sobre como usar Schedulers sequencialmente e simultaneamente.
Espero que isto ajude,
Softjake
fonte
Esta postagem do blog fornece uma excelente resposta
Na postagem do blog:
Schedulers.io () é apoiado por um pool de encadeamentos ilimitado. É usado para trabalhos de tipo de E / S que não consomem muita CPU, incluindo interação com o sistema de arquivos, realização de chamadas de rede, interações de banco de dados, etc.
Schedulers.computation () é apoiado por um conjunto de encadeamentos limitado com tamanho até o número de processadores disponíveis. É usado para trabalhos computacionais ou intensivos em CPU, como redimensionar imagens, processar grandes conjuntos de dados, etc. Cuidado: quando você aloca mais encadeamentos de computação que os núcleos disponíveis, o desempenho diminui devido à alternância de contexto e sobrecarga de criação de encadeamento à medida que os encadeamentos disputam tempo dos processadores.
Schedulers.newThread () cria um novo thread para cada unidade de trabalho agendada. Esse agendador é caro, pois o novo encadeamento é gerado toda vez e não ocorre reutilização.
Schedulers.from (executor do executor) cria e retorna um agendador personalizado suportado pelo executor especificado. Para limitar o número de threads simultâneos no pool de threads, use Scheduler.from (Executors.newFixedThreadPool (n)). Isso garante que, se uma tarefa for agendada quando todos os threads estiverem ocupados, ela será colocada na fila. Os encadeamentos no pool existirão até que seja explicitamente encerrado.
Thread principal ou AndroidSchedulers.mainThread () é fornecido pela biblioteca de extensões RxAndroid para RxJava. O thread principal (também conhecido como thread da interface do usuário) é onde a interação do usuário acontece. Deve-se tomar cuidado para não sobrecarregar esse encadeamento para impedir a interface do usuário instável e sem resposta ou, pior, a caixa de diálogo Application Not Responding ”(ANR).
Schedulers.single () é novo no RxJava 2. Esse agendador é apoiado por um único encadeamento que executa tarefas sequencialmente na ordem solicitada.
Schedulers.trampoline () executa tarefas de maneira FIFO (Primeira entrada, Primeira saída) por um dos segmentos de trabalho participantes. É frequentemente usado na implementação da recursão para evitar o aumento da pilha de chamadas.
fonte