Threads, o que são e como executar?

2014/09/12

Threads são linhas de execução concorrente, alguns autores chamam Threads de processos, mas em Java uma Thread não é um processo pois ela não recebe um process ID do sistema operacional.

Basicamente são códigos distintos que executam "ao mesmo tempo", na verdade essas linhas não são executadas ao mesmo tempo, elas são executadas de forma concorrente, isso significa que elas disputam "fatias de tempo" do processador, dessa forma cada uma executa um pouquinho de código de cada vez.

Como a troca de contextos do processador acontece de forma muito rápida, a percepção que temos é de que os códigos são executados ao mesmo tempo, ou paralelamente, mas vale lembrar que na verdade eles executam concorrentemente.

Para criar e executar uma Thread em Java, basta fazer o seguinte:

Abaixo tempos um exemplo prático, compile e execute o código e veja o que acontece:

/**
 * Exemplo de execução concorrente em Java
 *
 * @author Ricardo Artur Staroski
 */
public class Exemplo {

    // essa linha de execução só vai imprimir os números de 0 a 10
    class ImpressorDeNumeros implements Runnable {

        // esse é o método que será executado concorrentemente
        @Override
        public void run() {
            imprimeNumeros();
        }
    }

    // essa linha de execução vai imprimir as letras de 'a' a 'z'
    class ImpressorDeLetras implements Runnable {

        // esse é o método que será executado concorrentemente
        public void run() {
            imprimeLetras();
        }
    }

    /**
     * esse é o método principal, o ponto de entrada do nosso exemplo
     */
    public static void main(String[] args) {
        // vamos instanciar esta classe
        Exemplo exemplo = new Exemplo();
        // e agora vamos executá-la
        exemplo.executa();
    }

    // método que executa nosso exemplo
    private void executa() {
        // criar os objetos Runnable
        Runnable concorrente1 = new ImpressorDeLetras();
        Runnable concorrente2 = new ImpressorDeNumeros();

        // criar as linhas de execução concorrente para os objetos
        Thread linhaExecucao1 = new Thread(concorrente1);
        Thread linhaExecucao2 = new Thread(concorrente2);

        // disparar as linhas de execução
        linhaExecucao1.start();
        linhaExecucao2.start();

        // as outras duas linhas de execução já estão em andamento "ao mesmo tempo"
        // agora vamos imprimri qualquer coisa "ao mesmo tempo" que elas
        imprimeQualquerCoisa();
    }

    // método que imprime os números de 0 à 9
    private void imprimeNumeros() {
        for (int numero = 0; numero <= 9; numero++) {
            System.out.println("imprimindo numero " + numero);
            esperaUmPouquinho();
        }
    }

    // método que imprime as letras de 'a' à 'z'
    private void imprimeLetras() {
        for (char letra = 'a'; letra <= 'z'; letra++) {
            System.out.println("imprimindo letra " + letra);
            esperaUmPouquinho();
        }
    }

    // método que imprime qualquer coisa
    private void imprimeQualquerCoisa() {
        for (int i = 1; i <= 50; i++) {
            System.out.println("imprimindo qualquer coisa " + i);
            esperaUmPouquinho();
        }
    }

    // método espera meio segundo antes de continuar
    private void esperaUmPouquinho() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}