Pergunta

O que são Threads? O que é MultiThreading?

Resposta

É comum que programas realizem várias tarefas, mas em certos casos, é necessário ou útil que tais tarefas possam ser executadas "simultaneamente", isto é, que duas ou mais partes de um mesmo programa, digamos suas sub-tarefas,) esteja ativas, sendo executadas ao mesmo tempo. Na verdade, o sistema operacional deve controlar a execução destas partes, dividindo o tempo do(s) processador(es) do sistema entre tais sub-tarefas, da forma mais transparente possível para o usuário e para o programador.

Uma thread é como uma sub-tarefa de um programa, ou mais tecnicamente falando, uma linha de execução do programa. Enquanto um programa é usualmente tratado como um processo pelo sistema operacional, possuindo um espaço de endereçamento e recebendo sua quota de tempo de processamento do sistema, as threads de um processo compartilham seu espaço de endereçamento enquanto recebem, cada uma, sua quota de tempo de processamento, passando a impressão de que várias partes do programa estão em execução simultânea.

Um programa é multithreaded quando possui várias threads que o auxiliam a executar suas tarefas.

Existem inúmeras aplicações para programas multithreaded, tais como a construção de servidores capazes de atender "simultaneamente" com suas várias threads diferentes clientes (processos externos). Outra possibilidade de uso é a construção de interfaces capazes de responder mais prontamente, por exemplo, botões que permitam pausar ou cancelar operações durante sua operação.

O Java oferece recursos que facilitam a criação de programas multithreaded. A classe java.lang.Thread representa uma abstração de uma thread assim como a interface java.lang.Runnable que representa a especificação a ser seguinda por classes que pretendam ser tratadas como threads (veja JavaFaq 0064 para um discussão sobre interfaces).

Para criarmos uma thread geralmente definimos uma subclasse da java.lang.Thread onde implementamos o método run() tal como abaixo:

public class Contador extends Thread {
  // variáveis da class (opcionais)
  private String id;      // identificador
  private int inicio;     // valor de início da contagem
  private int fim;        // valor de término da contagem
  private int incremento; // valor do incremento da contagem
  // construtor (opcional)
  public Contador(String s, int i, int f, int inc) {
    id = s;
    inicio = i;
    fim = f;
    incremento = inc;
  }
  // código da thread
  public void run() {
    for(int c = inicio; c<=fim; c+=incremento)
      System.out.println(id+":"+c);
  }
}

O método run() corresponde ao trecho de código associado a thread que se pretende construir. O código contido neste método tem sua execução controlado pelos métodos:

Estes métodos (e outros disponíveis na classe java.lang.Thread) permitem controlar uma ou mais threads definidas por um programa.

A seguir um pequeno exemplo que usa a classe Contador dada acima:

public class ThreadDemo {
  public static void main(String args[]) {
    Contador c1 = new Contador("Contador 1", 0, 5, 1);
    Contador c2 = new Contador("Contador 2", 10, 40, 5);
    Contador c3 = new Contador("Contador 3", 100, 600, 100);
    c1.start();
    c2.start();
    c3.start();
  }
}

No exemplo criamos três contadores com valores distintos de início, fim e incremento. Embora sejam iniciados sequencialmente note que suas saídas (identificadas pelas strings dadas) ocorrem "embaralhadas" indicando que os três contadores estão em execução "simultânea". Um possível resultado pode ser visto abaixo.

>java ThreadDemo
Contador 1:0
Contador 2:10
Contador 2:15
Contador 3:100
Contador 1:1
Contador 1:2
Contador 2:20
Contador 1:3
Contador 1:4
Contador 3:200
Contador 3:300
Contador 2:25
Contador 2:30
Contador 2:35
Contador 2:40
Contador 1:5
Contador 3:400
Contador 3:500
Contador 3:600