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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top