Aula prtica de Concorrncia Equipe de Monitoria Bruno
Aula prática de Concorrência Equipe de Monitoria: Bruno Pereira - bpe Davi Pires - dpr Guilherme Barros – gbs 2 Thiago Cavalcanti - trc
Roteiro Motivação Concorrência em Java Como podemos criar threads em Java Formas de sincronização entre threads Conclusão Exercícios
Motivação Concorrência: Executa tarefas de controle de forma concorrente, onde diferentes partes do software estão rodando em paralelo. O paralelismo pode ser real (quando existem vários processadores) ou simulado (por sistemas operacionais tempo real nos quais as tarefas são escalonadas para compartilhar o processador)
Concorrência em JAVA Garbage collection Interface Gráfica Objetivo Mostrar como criar e controlar threads em uma aplicação Java
Como podemos criar threads Iremos mostrar como criar threads simples que imprimem mensagens em um buffer das duas formas. O primeiro exemplo consiste de duas classes que são descritas a seguir: Thread. Heranca: Classe que representa uma thread criada a partir da herança da classe java. lang. Thread Principal: Contem o método main que cria o buffer e as threads que irão acrescentar caracteres ao buffer
Thread. Heranca public class Thread. Heranca extends java. lang. Thread{ private String. Buffer buf; private String texto; public Thread. Heranca(String. Buffer buf, String texto){ this. buf = buf; this. texto = texto; } public void run(){ for(int i=0; i < 10; i++){ buf. append(texto); try { sleep((long)(Math. random() * 100)); } catch (Interrupted. Exception ie) { } }
Principal public class Principal{ public static void main(String []args){ String. Buffer buf = new String. Buffer(); Thread. Heranca her 1 = new Thread. Heranca(buf, "thread 1n"); Thread. Heranca her 2 = new Thread. Heranca(buf, "thread 2n"); Thread. Heranca her 3 = new Thread. Heranca(buf, "thread 3n"); her 1. start(); her 2. start(); her 3. start(); for(int i=0; i < Integer. MAX_VALUE/10; i++); System. out. println(buf. to. String()); } }
Como podemos criar threads Bem falta agora mostrar a segunda forma de se criar uma thread em Java: através da interface java. lang. Runnable. Para isso basta fazermos pouquíssimas modificações no exemplo anterior. A classe Thread. Interface substitui a classe Thread. Heranca.
Thread. Interface public class Thread. Interface implements Runnable{ private String. Buffer buf; private String texto; public Thread. Interface(String. Buffer buf, String texto){ this. buf = buf; this. texto = texto; } public void run(){ for(int i=0; i < 20; i++) { buf. append(texto); for(int j=0; j < Integer. MAX_VALUE/600; j++); } } }
Principal 2 public class Principal 2{ public static void main(String []args){ String. Buffer buf = new String. Buffer(); Thread inter 1 = new Thread(new Thread. Interface(buf, "thread 1n")); Thread inter 2 = new Thread(new Thread. Interface(buf, "thread 2n")); Thread inter 3 = new Thread(new Threadinterface(buf, "thread 3n")); inter 1. start(); inter 2. start(); inter 3. start(); for(int i=0; i < Integer. MAX_VALUE/10; i++); System. out. println(buf. to. String()); } }
Sincronização Semáforos Monitor (synchronized) Formas de sincronização Competição – tentam utilizar o mesmo recurso compartilhado Cooperação – a comunicação entre as threads é necessária
Sincronização por competição Iremos mostrar agora como sincronizar várias threads que competem por um recurso compartilhado. A idéia é parecida com o exemplo anterior aonde várias threads adicionam um String num buffer compartilhado. Ao invés de usarmos um objeto String. Buffer como buffer, vamos criar o nosso próprio buffer através da classe Buffer. java que está descrita abaixo
Buffer. java public class Buffer{ private String. Buffer buf; public Buffer(){ buf = new String. Buffer(); } public synchronized void add(String novo){ for(int i=0; i < novo. length(); i++) buf. append(novo. char. At(i)); } public synchronized void print(){ System. out. println(buf); }
Thread. Heranca 2. java public class Thread. Heranca 2 extends Thread{ private Buffer buf; private String texto; public Thread. Heranca 2(Buffer buf, String texto){ this. buf = buf; this. texto = texto; } public void run(){ for(int i=0; i < 4000; i++) buf. add(texto); } }
Principal 3. java public class Principal 3{ public static void main(String []args){ Buffer buf = new Buffer(); Thread. Heranca 2 . . . her 1 her 2 her 3 her 4 her 5 her 6 = = = new new new Thread. Heranca 2(buf, "thread "thread 1n"); 2n"); 3n"); 4n"); 5n"); 6n");
Principal 3. java her 1. start(); her 2. start(); her 3. start(); her 4. start(); her 5. start(); her 6. start(); for(int i=0; i < Integer. MAX_VALUE/10; i++); buf. print(); } }
Um teste simples Retirem a palavra-chave synchronized do método add da classe Buffer E executem! E ai? Alguma esquisitice? Use sabiamente essa palavra!
Sincronização por cooperação Imagine que a thread principal da aplicação (aquela que contém o método main) vai imprimir o conteúdo de um buffer, contudo ela apenas deve imprimir quando o buffer estiver cheio. Outras threads ficarão concorrentemente adicionando caracteres ao buffer até preenchê-lo. Primeiro vamos ver a classe Buffer 2 que implementa o buffer que vamos utilizar
Buffer 2. java public class Buffer 2{ private char[] buf; private int tam; private final int MAX = 100; public Buffer 2(){ buf = new char[MAX]; tam = 0; }
Buffer 2. java public synchronized void inserir(char c){ if(tam==MAX) notify(); else buf[tam++] = c; } public synchronized String esvaziar(){ if(tam < MAX) try{ wait(); }catch(Interrupted. Exception ie){ } tam = 0; return new String(buf); } }
Thread. Heranca 3. java
Thread. Heranca 3. java public class Thread. Heranca 3 extends Thread{ private Buffer 2 buf; private char c; public Thread. Heranca 3(Buffer 2 buf, char c){ this. buf = buf; this. c = c; } public void run(){ for(int i=0; i < 1000; i++){ buf. inserir(c); try { sleep((long)5); } catch (Interrupted. Exception ie) { } } }
Principal 4. java public class Principal 4{ public static void main(String []args){ Buffer 2 buf = new Buffer 2(); Thread. Heranca 3 her 1 = new Thread. Heranca 3(buf, '1'); Thread. Heranca 3 her 2 = new Thread. Heranca 3(buf, '2'); Thread. Heranca 3 her 3 = new Thread. Heranca 3(buf, '3'); her 1. start(); her 2. start(); her 3. start(); String result; for(int i=0; i < 10; i++){ result = buf. esvaziar(); System. out. println("nn. Impressao # " + (i+1) + ": n Buffer = " + result + " -> Tamanho: " + result. length()); } } }
Ultimas considerações wait() notify() E as 2 pilhas de JAVA
Ciclo de vida de uma thread start Nascimento Tempo para adormecer expira notify ou notify. All Pronto Inicia E/S Executando wait Esperando Conclusão de E/S alocar um processo sleep Adormecido completo Morto Bloqueado
Aula prática de Concorrência Equipe de Monitoria: Bruno Pereira - bpe Davi Pires - dpr Guilherme Barros – gbs 2 Thiago Cavalcanti - trc
- Slides: 26