Buscar

PROGRAMAÇÃO ORIENTADA A OBJETOS Aula 10

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

- -1
PROGRAMAÇÃO ORIENTADA A OBJETOS
DESENVOLVENDO APLICATIVOS COM 
THREADS, CONCORRÊNCIA E GUI SWING
- -2
Olá!
Nesta aula, você irá:
1. Aprender a utilizar múltiplos Threads separados para modificar conteúdos exibidos em uma GUI Swing.
2. Aprender a trabalhar de forma sincronizada com cada um dos Threads.
3. Aprender a criar e executar um aplicativo de múltiplos threads.
Threads e Swing
Os componentes GUI Swing não são seguros quanto ao uso de Threads, quer dizer que se múltiplas Threads
acessam um componente Swing, os resultados podem não estar corretos. Todas as interações com componentes
Swing devem ser executadas a partir de uma Thread de cada vez. Normalmente, esta Thread é uma Thread de
tratamento ou execução de eventos.
É fundamental que uma tela GUI Swing não congele, podendo responder ao usuário sempre que necessário.
Então, para criar um programa que responda as necessidades do usuário, o programador precisa aprender como
a estrutura Swing trabalha com Threads:
• Thread Inicial: executa o código inicial da aplicação
• Thread de tratamento de evento: onde todo o tratamento de eventos é feito. A maioria das interações 
com componentes Swing devem ser feitos através deste Thread.
• Thread de trabalho – worker: processos executados em segundo plano, que consomem 
processamento.
Tratamento de Evento – Event dispatching
A classe SwingUtilities fornece dois métodos para ajudar a fazer o tratamento de eventos na execução do
programa. São eles:
• invokeLater(): Solicita que algum código seja executado na Thread de despacho de evento. Este método 
retorna imediatamente a execução do código, sem que seja necessário esperar.
• invokeAndWait(): Atua muito semelhante ao invokeLater(), exceto pelo fato de esperar pela execução 
do código. Como regra, procure utilizar sempre o método invokeLater() ao invés deste.
•
•
•
•
•
- -3
Produtor / Consumidor com Buffer e GUI
Vamos implementar um algoritmo Produtor / Consumidor com um Buffer de cinco posições:
Este programa será composto por:
Produtor
inteiro
Classe responsável pela produção do conteúdo e disponibilizado na área compartilhada;
- -4
Consumidor
inteiro
Classe responsável pelo consumo do conteúdo disponibilizado na área compartilhada;
B u f f e r
Inteiro
Sincronizado
O local onde será feito a sincronização da leitura e da escrita em um buffer de cinco
posições;
Atualiza
Thread
Thread responsável pela comunicação entre os Threads e a Interface Gráfica;
B u f f e r
Rotativo
Classe responsável pela configuração, disparo e recebimento das informações dos
produtores e consumidores. É onde se encontra o procedimento main();
Podemos observar que foi colocado uma configuração para iniciar a produção. A produção é iniciada ao clicar no
botão Inicia Produção. Este fica desabilitado até que a o Consumidor consuma todos os 10 elementos.
As barras de rolagem representam o tempo que queremos esperar para produzir ou consumir. É o tempo de
simulação ocupada, na qual o Thread dorme.
Vamos ver a saída do programa:
- -5
O Produtor Inteiro – ProdutorInteiro
O código do produtor inteiro está apresentado abaixo:
import javax.swing.SwingUtilities;
/**
*
* @author Eduardo
*/
public class ProdutorInteiro extends Thread {
private BufferInteiroSincronizado objetoCompartilhado;
private BufferRotativo areaSaida;
private int tempoProducao = 500;
public ProdutorInteiro(BufferInteiroSincronizado compartilhado,
BufferRotativo saida){
super("ProdutorInteiro");
objetoCompartilhado = compartilhado;
areaSaida = saida;
}
public ProdutorInteiro(BufferInteiroSincronizado compartilhado,
BufferRotativo saida, float tempo){
super("ProdutorInteiro");
objetoCompartilhado = compartilhado;
areaSaida = saida;
tempoProducao = (int)(1000*tempo);
}
public void run(){
for (int cont=1; cont<=10; cont++){
try{
Thread.sleep((int)(Math.random()*tempoProducao));
}
catch(InterruptedException exception){
System.err.println(exception.toString());
}
- -6
objetoCompartilhado.setSharedInt(cont);
}
SwingUtilities.invokeLater(new AtualizaThread(areaSaida,
"\n"+ getName() + " Finalizando de produzir valores"+
"\nTerminando "+getName()+"\n", false));
}
}
Podemos observar que para o Thread falar com a GUI, ele precisa do SwingUtilities chamando o Thread
AtualizaThread. Tanto o produtor quanto o consumidor vão receber via parâmetro a GUI (BufferRotativo) e o
tempo de espera.
Consumidor Inteiro – ConsumidorInteiro
Agora vamos observar o código do Consumidor:
import javax.swing.SwingUtilities;
/**
*
* @author Eduardo
*/
public class ConsumidorInteiro extends Thread{
private BufferInteiroSincronizado objetoCompartilhado;
private BufferRotativo areaSaida;
private int tempoConsumidor=3000;
public ConsumidorInteiro (BufferInteiroSincronizado compartilhado,
BufferRotativo saida){
super("ConsumidorInteiro");
objetoCompartilhado = compartilhado;
areaSaida= saida;
}
public ConsumidorInteiro (BufferInteiroSincronizado compartilhado,
BufferRotativo saida, float tempo){
super("ConsumidorInteiro");
objetoCompartilhado = compartilhado;
areaSaida= saida;
- -7
tempoConsumidor = (int)(1000*tempo);
}
@Override
public void run(){
int valor, soma=0;
do{
try{
Thread.sleep((int)(Math.random()*tempoConsumidor));
}
catch(InterruptedException exception){
System.err.println(exception.toString());
}
valor=objetoCompartilhado.getSharedInt();
soma+=valor;
}while(valor!=10);
SwingUtilities.invokeLater(new AtualizaThread(areaSaida,
"\n"+getName()+" consumido valores totalizando: "+soma+
"\nTerminando "+getName()+"\n", true));
}
}
Não há nada de diferente que seja necessário um comentário.
Área Compartilhada – BufferInteiroCompartilhado
Vamos ver o código:
import java.text.DecimalFormat;
import javax.swing.*;
/**
*
* @author Eduardo
*/
public class BufferInteiroSincronizado {
private int sharedInt [] = {-1, -1, -1, -1, -1};
private boolean escrever = true;
- -8
private boolean ler = false;
private int posicaoLeitura = 0, posicaoEscrita = 0;
private BufferRotativo saidaArea;
public BufferInteiroSincronizado (BufferRotativo saida){
saidaArea = saida;
}
public synchronized void setSharedInt(int valor){
while(!escrever){
try{
SwingUtilities.invokeLater( new AtualizaThread(
saidaArea, " Esperando para Produzir " + valor, false));
wait();
}
catch(InterruptedException exception){
System.err.println(exception.toString());
}
}
sharedInt[posicaoEscrita]=valor;
ler=true;
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\nProduzido " + valor+" na celula "+posicaoEscrita, false));
posicaoEscrita = (posicaoEscrita + 1)%5;
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\tEscrita " + posicaoEscrita + "\tLeitura "+ posicaoLeitura, false));
displayBuffer(saidaArea, sharedInt);
if(posicaoEscrita==posicaoLeitura){
escrever= false;
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\nBUFFER LOTADO", false));
}
notify();
}
- -9
public synchronized int getSharedInt(){
int valor;
while(!ler){
try{
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
" ESPERANDO PARA CONSUMIR", false));
wait();
}
catch(InterruptedException exception){
System.err.println(exception.toString());
}
}
escrever = true;
valor = sharedInt[posicaoLeitura];
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\nConsumido "+valor+" da célula "+posicaoLeitura, false));
posicaoLeitura=(posicaoLeitura + 1) % 5;
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\tEscrita "+ posicaoEscrita +"\tLeitura"+
posicaoLeitura, false));
displayBuffer(saidaArea, sharedInt);
if(posicaoLeitura==posicaoEscrita){
ler=false;
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\nBUFFER VAZIO", false));
}
notify();
return valor;
}
public void displayBuffer(BufferRotativo AreaSaida, int buffer[]){
DecimalFormat formatoNumero = new DecimalFormat(" #;-#" );
StringBuffer bufferSaida = new StringBuffer();
- -10
for (int cont=0; cont<buffer.length;cont++)bufferSaida.append(" "+formatoNumero.format(buffer[cont]));
SwingUtilities.invokeLater(new AtualizaThread(saidaArea,
"\tbuffer: "+bufferSaida, false));
}
}
Esta classe possui um buffer de inteiros de cinco posições. Observe como é feita a atribuição dos novos valores
de leitura e escrita:
posicaoLeitura=(posicaoLeitura + 1) % 5;
Nesta linha, posiçãoLeitura recebe um valor de 1 até 5 independente do valor da posição. Isso se dá porque
estamos pegando o resto da divisão com o operador %.
Neste algoritmo teremos um controle de posicionamento para leitura e outro para escrita.
É fundamental também identificar se o Buffer está cheio ou vazio. Em ambos os casos, algum Thread irá dormir.
No caso do Buffer cheio, o produtor precisa esperar o consumidor consumir enquanto que se o Buffer estiver
vazio, o consumidor não pode consumir e precisa esperar.
Para mostrar como está sendo a evolução do programa e dos Threads, a comunição com a GUI é feita através do
SwingUtilities.
Os métodos Get’s e Set’s determinam como o produtor e como o consumidor irão compartilhar os recursos. Eles
têm algoritmos próprios para controlar o funcionamento dos Threads.
Existe também o método DisplayBuffer que serve somente para formatar o buffer para que ele possa ser
apresentado decentemente.
Atualiza GUI – AtualizaThread
Este Thread é o responsável pela comunicação entre os Threads e a GUI. Tudo que o usuário precisar manipular
na tela, precisará ter um método e deverá ser acessado neste objeto.
No método run(), o Thread chama dois métodos do Objeto principal, que são adiciona e habilitaProdução. O
método adiciona acrescenta uma linha no Componente JTextArea. Já o método habilitaProdução recebe um
booleano para verificar se o conjunto de Threads ainda está produzindo ou não. Quando é encerrado a produção,
é enviado um sinal true para este método para que o botão de início de produção seja habilitado. Com isso,
podemos controlar a nossa tela dinamicamente, sempre que ocorre alguma coisa nos Threads. No caso, foi
implementado apenas uma área de texto para receber mensagens e a habilitação de um botão.
Vamos ver o código:
public class AtualizaThread extends Thread{
- -11
private BufferRotativo saidaArea;
private String msgSaida;
private boolean habilita;
public AtualizaThread(BufferRotativo saida, String msg, boolean h){
saidaArea = saida;
msgSaida = msg;
habilita = h;
}
public void run(){
saidaArea.adiciona(msgSaida);
saidaArea.habilitaProducao(habilita);
}
}
Para finalizarmos o assunto desta aula, leia "Programa Principal - BufferRotativo", no link:
http://estaciodocente.webaula.com.br/cursos/gon282/docs/14POO_aula10_doc01.pdf
CONCLUSÃO
Nesta aula, você:
• Aprendeu a utilizar múltiplos Threads separados para modificar conteúdos exibidos em uma GUI Swing.
• Aprendeu a trabalhar de forma sincronizada com cada um dos Threads.
• Aprendeu a criar e executar um aplicativo de múltiplos threads.
Saiba mais
Para esta aula sugiro as seguintes tarefas:
• Leitura do Capítulo 23 (23.6 até 23.7) do livro Java como programar, 6ª Edição, 
de H. Deitel e P. Deitel, Editora Pearson Education, 2005.
• Resolução dos exercícios de 23.5 até 23.9 do capítulo 23 do livro Java Como 
Programar – 6ª Edição.
•
•
•
•
•
http://estaciodocente.webaula.com.br/cursos/gon282/docs/14POO_aula10_doc01.pdf
	Olá!
	
	CONCLUSÃO

Continue navegando