Вы находитесь на странице: 1из 6

THREADS EM JAVA

Gabriel de Oliveira Ramos <gabriel.oliveira.ramos@gmail.com> Roland Teodorowitsch <roland@ulbra.br> - Orientador


Universidade Luterana do Brasil (Ulbra) Curso de Cincia da Computao Campus Gravata Av. Itacolomi, 3.600 Bairro So Vicente CEP 94170-240 Gravata - RS

15 de novembro de 2009

RESUMO
Este artigo apresenta o uso de threads na linguagem de programao Java, descrevendo a classe Thread bem como a interface Runnable. Menciona ainda algumas consideraes importantes, como o ciclo de vida de threads, bem como questes sobre prioridades e sincronizao de threads. Ao final, mostra um exemplo de aplicativo que utiliza threads bem como uma anlise de desempenho de sua execuo com e sem threads. Palavras-chave: Thread; Java.

ABSTRACT
Title: Java Threads This paper presents the use of threads in Java programming language, describing the Thread class and the Runnable interface. It mentions too some important considerations about the threads lifecycle and something about threads priorities and synchronization. Finally, shows a thread application example and an analysis of its execution. Keywords: Thread; Java.

INTRODUO

O desempenho computacional um assunto amplamente discutido desde os primrdios da computao. Atualmente, a maioria dos sistemas operacionais trabalha com multiprocessamento para conferir maior desempenho na execuo de processos. Em um sistema operacional multiprocessado, algoritmos de escalonamento so utilizados para dividir a utilizao da CPU entre os processos em execuo. Este mecanismo confere uma resposta muito mais gil para o usurio uma vez que as tarefas parecem ser executadas ao mesmo tempo. Entretanto, este mecanismo no torna a execuo de duas etapas distintas de um processo paralelas, torna paralela apenas a execuo dos processos entre si. neste ponto que se torna necessrio o uso de threads. Threads podem ser definidas como fluxos seqencias de execuo de um programa. Logo, um programa pode dividir partes seqenciais no concorrentes de sua execuo em threads distintas, conferindo paralelismo na execuo destas. Claro, partes concorrentes podem ser separadas em threads tambm, entretanto este tipo de procedimento no confere paralelismo, no justificando o uso desta tcnica. Este artigo fala sobre o uso de threads na linguagem Java. Neste contexto, este artigo descreve a classe Thread e a interface Runnable, que podem ser utilizadas para se trabalhar com threads em Java. Na seqencia abordado o ciclo de vida de uma thread na mquina virtual Java (JVM), prioridades e sincronizao de threads. Est presente neste artigo, tambm, um exemplo de aplicativo que utiliza threads, bem como uma anlise do resultado de suas execues utilizando quantidades variadas de threads.

THREADS EM JAVA

A mquina virtual Java permite que uma aplicao tenha diversos fluxos seqncias de execuo rodando concorrentemente (SUN, 2009a). Para se utilizar esta funcionalidade, a API Java disponibiliza a classe Thread e a interface Runnable.

2.1

A classe Thread

A classe Thread uma classe nativa da linguagem Java, existente desde a API 6.1, que permite representar um fluxo independente de execuo dentro de um programa (JANDL, 2007, p. 262). Pode-se 1

definir uma thread a partir da criao de uma classe filha de Thread, ou seja, uma subclasse. Uma subclasse de Thread exige a implementao do mtodo run(), que contm o cdigo a ser executado pela thread em si. A Figura 1 mostra um exemplo de cdigo de uma classe filha de Thread que cria aleatoriamente nmeros de 0 a 99, parando apenas ao encontrar o nmero 50.
public class ExemploThread extends Thread { public void run() { int total = 0; while ((int)(Math.random()*100) != 50) total++; System.out.println("Sou a " + this.getName() + " e tentei " + total + " vezes."); } }

Figura 1 Exemplo de subclasse de Thread Para criar uma thread propriamente dita a partir de uma subclasse de Thread, basta declarar um objeto desta, utilizando o operador new para instanci-la, bem como em qualquer outro tipo de objeto em Java. Instanciado o objeto a thread est pronta para ser rodada. Para isto, deve-se chamar o mtodo start(), responsvel por providenciar o seu escalonamento pelo sistema operacional e por executar o mtodo run() (JANDL, 2007, p. 263). A Figura 2 mostra um exemplo deste processo de criao da thread.
ExemploThread t = new ExemploThread(); t.start();

Figura 2 Exemplo de instanciao de um objeto de Thread e sua conseqente execuo Ao executar este cdigo mais de uma vez, o resultado obtido pode ser o mesmo ou no, refletindo mais o estado do sistema do que da aplicao em si (JANDL, 2007, p.264). A JVM mantm um programa em execuo enquanto suas threads permanecem ativas. De acordo com a Sun (2009a), uma thread finalizada quando chega ao fim do mtodo run() ou quando gera uma exceo no tratada, fazendo com que esta ltima seja lanada para o nvel superior.

2.2

A interface Runnable

Segundo a Sun (2009b), a linguagem de programao Java no permite herana mltipla, no entanto h uma alternativa para o uso de mais de uma superclasse, que a utilizao de interfaces. Com base neste conceito, desde a API 6.2 existe a interface Runnable, que possui um funcionamento bem semelhante ao da classe Thread, ao exigir a implementao do mtodo run(). Diferente de implementaes que utilizam a classe Thread diretamente, as que utilizam a interface Runnable possuem algumas particularidades. Aps instanciar o objeto que possui a interface Runnable, necessrio instanciar tambm um objeto da classe Thread que receba em seu mtodo construtor uma referncia ao objeto da interface Runnable, bem como um nome para a thread criada. Aps instanciar este objeto da classe Thread, pode-se iniciar a thread a partir do seu mtodo start(). A Figura 3 mostra um exemplo de uma classe que implementa a interface Runnable, bem como da chamada desta classe a partir da criao de um objeto de Thread.
public class ExemploRunnable implements Runnable { public void run() { int total = 0; while ((int)(Math.random()*100) != 50) total++; } } public class Main { public static void main(String[] args) { ExemploRunnable r = new ExemploRunnable(); Thread t = new Thread(r, "Thread 1"); t.start(); } }

Figura 3 Exemplo de utilizao de uma interface Runnable

Esta interface torna-se muito importante, pois em diversos momentos necessrio que uma classe tenha dois pais ao mesmo tempo. Um bom exemplo deste tipo de aplicao para interfaces grficas. Uma classe criada para fazer uma janela, por exemplo, pode ser filha da classe JPanel e, para possibilitar paralelismo e uma melhor experincia para o usurio, pode implementar a classe Runnable.

2.3

Ciclo de vida de uma Thread

Uma thread, do momento em que criada at o qual finalizada, passa por diversos estados e transies. Este conjunto de estados e transies caracteriza o ciclo de vida de uma thread, o qual pode ser visualizado na Figura 4.

Figura 4 Ciclo de vida de threads Como mencionado anteriormente, as threads so criadas a partir de sua instanciao. Ao disparar o mtodo start(), ela ser colocada na lista de threads prontas a serem executadas pelo sistema operacional. Quando o sistema operacional seleciona uma thread para ser executada, ela permanece no estado Execuo, produzindo as aes do mtodo run(). Segundo Jandl (2007), uma thread permanece em Execuo at que: seu tempo de uso da CPU se esgote ou com a chamada do mtodo yield() quando executa um sleep(), permanecendo no estado Suspenso durante o tempo estabelecido e voltando ao estado Pronto, em seguida; quando executa um wait(), permanecendo no estado Suspenso at que outra thread execute um notify() ou notifyAll(), voltando ao estado Pronto em seguida; quando necessita de uma operao de I/O, ficando no estado Bloqueado at que a operao seja concluda, voltado ao estado Pronto; se a thread finalizar a execuo do seu mtodo run() ou quando for executado o mtodo interrupt(), indo para o estado Finalizado.

2.4

Prioridades

A prioridade de uma thread corresponde a preferncia que ela ter perante as demais durante sua execuo. Quanto maior a prioridade de uma thread, maior ser sua preferncia no uso da CPU. Threads de mesma prioridade costumam partilhar o tempo de CPU igualmente. A prioridade extremamente ligada ao algoritmo de escalonamento de CPU que o sistema operacional utiliza. Para definir a prioridade de uma thread, so usados nmeros de 1 a 10, sendo que o nmero 5 usado para definir a prioridade como normal. Entretanto, nem todos os sistemas operacionais possuem as mesmas prioridades de uma thread Java. Portanto, para garantir que uma thread com prioridade 10 tenha prioridade alta tanto em um sistema operacional cuja prioridade mxima seja 10 quanto em outro que seja 100, a JVM traduz a prioridade especificada no cdigo para a do sistema operacional, logo uma prioridade 10 em Java pode ser traduzida para uma prioridade 100, por exemplo.

2.5

Sincronizao

Durante a execuo de threads, h casos em que elas trabalham independentemente uma da outra, sem necessidade de qualquer comunicao entre elas e h casos em que elas comunicam-se de alguma forma ou utilizam dados em comum, denominadas assncronas e sncronas, respectivamente. Em threads sncronas, geralmente necessrio que a informao que est sendo compartilhada seja consistente, evitando que duas threads mexam nesta ao mesmo tempo, gerando um resultado inconsistente. Para tanto, na linguagem Java h um mecanismo de sincronizao, onde esta consistncia pode ser garantida. Tal mecanismo pode ser utilizado com a palavra reservada synchronized, aplicada a um mtodo, a um bloco ou mesmo a uma diretiva isolada. Os mtodos wait(), notify() e notifyAll() tambm so muito importantes na sincronizao, sendo responsveis por provocar, respectivamente: uma espera, a liberao de uma ou mais threads em espera (JANDAL, 2007, p. 282).

EXEMPLO PRTICO

Para demonstrar o funcionamento de threads foi feito um aplicativo em Java para simular a utilizao da distribuio de uma tarefa entre n elementos processadores, conhecidos na rea de sistemas distribudos como Eps (Elementos Processadores). A tarefa bsica: verificar se os nmeros de um dado intervalo so primos ou no.

3.1

O aplicativo

Neste aplicativo foram utilizadas duas classes: a classe EP, filha da classe Thread, que responsvel por realizar a tarefa; e a classe Main, que instancia os objetos da classe EP executando-os em seguida. Inicialmente definido na classe Main o nmero de threads a ser utilizado pelo aplicativo e o intervalo da seqncia de nmeros a ser processada. Estes valores so armazenados em variveis para que sejam utilizados posteriormente pela classe EP. Em seguida, as instncias da classe EP so criadas, recebendo como parmetros para seu mtodo construtor: o nmero da thread, iniciando em 0; o nmero total de threads, definido anteriormente; o incio e o fim do intervalo, tambm definidos anteriormente. Aps instanciadas, as threads tm sua execuo iniciada, para que a tarefa comece a ser resolvida. A classe EP utiliza alguns conceitos bsicos de computao distribuda. Portanto, foi necessrio dividir a seqncia de nmeros entre as threads existentes. Para tal finalidade, uma thread verifica todos os nmeros da seqncia que so mltiplos de seu nmero, recebido como parmetro no seu mtodo construtor. A Figura 5 mostra o cdigo-fonte das duas classes mencionadas.
public class Main { public static void main(String[] args) { //Varivel para determinar o nmero de threads int nEP = 2; //Variveis para determinar o intervalo a ser processado int iniS = 2, fimS = 1000; //Instanciao das threads EP ep0 = new EP(0, nEP, iniS, fimS); EP ep1 = new EP(1, nEP, iniS, fimS); //Incio da execuo das threads ep0.start(); ep1.start(); } } public class EP extends Thread { //Variveis para guardar o nmero da thread atual //e o nmero total de threads, respectivamente private int EPid, nEP;

//Variveis para determinar o intervalo a ser processado private int iniS, fimS; //Varivel para controlar se o nmero primo ou no private boolean primo; public EP(int EPid, int nEP, int iniS, int fimS) { this.EPid = EPid; this.nEP = nEP; this.iniS = iniS; this.fimS = fimS; } public void run() { //Percorre apenas os nmeroes correspondentes thread, //do intervalo especificado for (int x = EPid + iniS; x <= fimS; x = x + nEP) { //Limpa a varivel de controle primo = true; //Verifica se o nmero primo for (int y = 2; y < x; y++) if (x % y == 0) primo = false; //Imprime o resultado if (primo) System.out.println("O nmero " + x + " primo."); else System.out.println("O nmero " + x + " no primo."); } } }

Figura 5 Exemplo de um aplicativo utilizando threads Como pode ser observado na Figura 5, neste caso esto sendo utilizadas apenas duas threads para processar o intervalo de 2 a 1000.

3.2

Os resultados

Para demonstrar o desempenho do uso de threads em um aplicativo o cdigo da Figura 5 foi executado utilizando quantidades variadas de threads, com os tempos execuo contabilizados, para o intervalo de 2 a 100000 (entre dois e cem mil). Para tal tarefa foi utilizado um computador com processador Intel Core2 Duo que, por possuir dois ncleos fsicos, favorece a utilizao de threads. O sistema operacional utilizado foi o Windows Vista. A Tabela 1 apresenta os resultados obtidos nas diversas execues do aplicativo. Tabela 1 Relao dos tempos de execuo, em segundos, do aplicativo Threads utilizadas Tempo para 50000 nmeros Tempo para 100000 nmeros 1 22 76 2 16 54 4 15 54 8 15 49 16 14 50

Como pode ser observado na Tabela 1, a utilizao de mais de uma thread para executar uma tarefa traz grandes ganhos. Para um intervalo de cinqenta mil nmeros, tem-se um ganho de aproximadamente 27% utilizando duas threads e de aproximadamente 32% utilizando oito threads. J para um intervalo de

cem mil nmeros o ganho sobe para quase 29% quando se utilizam duas threads e para quase 36% utilizando oito threads. Percebe-se, portanto, que h um ganho considervel ao utilizar threads em um aplicativo.

CONCLUSO

Este artigo apresentou o uso de threads na linguagem de programao Java, bem como algumas de suas principais caractersticas e propriedades, esclarecendo de uma forma simplificada seus conceitos principais. Foi feita tambm uma anlise prtica dos benefcios que a utilizao de threads em um aplicativo pode trazer. Maiores detalhes e esclarecimentos mais aprofundados sobre o tema podem ser consultados nas referncias deste artigo.

REFERNCIAS
JANDL JUNIOR, Peter. Java: guia do programador. So Paulo: Novatec, 2007. 688 p. SUN Microsystems. Thread (Java Platform SE 7 b66). Santa Clara: SUN, 2009. Disponvel em: <http://java.sun.com/javase/7/docs/api/java/lang/Thread.html>. Acesso em: 17 out. 2009. SUN Microsystems. Interfaces. Santa Clara: SUN, 2009. Disponvel em: <http://java.sun.com/docs/books/tutorial/java/IandI/createinterface.html>. Acesso em: 18 out. 2009.