Você está na página 1de 44

Programação Concorrente

e Distribuída
Aula 3 – Programação paralela

Universidade Católica de Brasília Programação Concorrente e Distribuída


Ciência da Computação
JAVA

História do Java
 Projeto Green iniciou em 1991 com Patrick Naughton,
Mike Sheridan e James Gosling
 Primeiro produto *7 (StarSeven)
 Primeiro nome da linguagem
OAK (carvalho)

Duke baseado no emblema da federação da série de TV Star Trek


Universidade Católica de Brasília Programação Concorrente e Distribuída
Ciência da Computação Prof. Edson Francisco da Fonseca
JVM

• Máquina virtual Java (em inglês: Java Virtual Machine, JVM) é um


programa que carrega e executa os aplicativos Java, convertendo
os bytecodes em código executável de máquina.
• É um computador abstrato (virtual) definido por uma especificação.
• A JVM é responsável pelo gerenciamento dos aplicativos, à medida
que são executados.
• Graças à máquina virtual Java, os programas escritos em Java
podem funcionar em qualquer plataforma de hardware e software
que possua uma versão da JVM, tornando assim essas aplicações
independentes da plataforma onde funcionam.
PARALELISMO EM JAVA

Máquina Virtual Java, Processos e Threads


 Cada instância da JVM corresponde a um processo do sistema
operacional hospedeiro
 A JVM não possui o conceito de processos, apenas implementa
threads internamente
 Ao ser iniciada, a JVM executa o método main() do programa na
thread principal, e novas threads podem ser criadas a partir desta
 Threads de uma mesma JVM compartilham memória, portas de
comunicação, arquivos e outros recursos

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Implementação de threads no Java:


 Green Threads:
 Usadas em sistemas sem suporte a threads
 Threads e escalonamento implementados pela JVM
 Threads Nativas:
 Usa threads nativas e escalonador do SO
 Usada nos SO com suporte a thread: Linux, Windows, etc.
 Ideal em máquinas com mais de um processador

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Ciclo de Vida de Threads no Java

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Threads na Linguagem Java:


 O conceito de thread está presente no Java através da classe
java.lang.Thread
 Java também oferece:
 Mecanismos para sincronização e controle de concorrência entre
threads
 Classes para gerenciamento de grupos (pools) de threads
 Classes da API que podem ser acessadas concorrentemente
(thread-safe)

Universidade Católica de Brasília


Ciência da Computação
PROGRAMAR...

Universidade Católica de Brasília


Ciência da Computação
PROGRAMAR...

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA
Hello
public class Hello {
public void dizer() {
System.out.println("Hello world!");
}
}

Universidade Católica de Brasília


Ciência da Computação
Definindo e lançando uma Thread

• Um aplicativo que cria uma instância de


Thread deve fornecer o código que será
executado nesse thread.
• Existem três maneiras de fazer isso:
• Fornecendo um objeto Runnable.
• Especializando a classe Thread
• Criando um objeto da classe Thread e associando
uma instância executável
interface pública Runnable

• A interface Runnable deve ser implementada por


qualquer classe cujas instâncias sejam executadas
por um thread.
• A classe deve definir um método sem argumentos
chamado run.
• Essa interface foi projetada para fornecer um
protocolo comum para objetos que desejam executar
código enquanto estão ativos.
PARALELISMO EM JAVA
public class Hello implements Runnable {
Hello public void dizer() {
System.out.println("Hello world!");
}
public void run(){
this.dizer();
}
}

Alo public class Alo implements Runnable {


public void dizer() {
System.out.println("Alo mundo!");
}
public void run()
{ this.dizer();
}
}

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA
Principal

public class Principal {


public static void main(String[] args) {
Thread hello = new Thread(new Hello());
hello.run();

Thread alo = new Thread(new Alo(),"t2");


alo.run();
}
}

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Testar a aplicação

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Herança

Universidade Católica de Brasília


Ciência da Computação
Criando uma thread usando
herança da classe Thread

public class helloThread extends Thread {


public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new helloThread()).start();
}
}
PARALELISMO EM JAVA

Principais métodos:
 Construtores: Thread(), Thread (Runnable), Thread(String),
Thread(Runnable, String)...
 run(): contém o código executado pela thread. Definido na interface
Runnable. Implementado pela thread ou por um objeto passado
como parâmetro para seu construtor. Quando este método finaliza, a
thread também termina.
 start(): inicia a thread em paralelo com a thread que a criou,
executando o código contido no método run(). Este método chama o
método run() antes de terminar.
Universidade Católica de Brasília
Ciência da Computação
PARALELISMO EM JAVA

Threads em Java usando herança:

Hello
public class Hello extends Thread {
public void run() {
System.out.println("Hello world!");
}
}

Universidade Católica de Brasília


Ciência da Computação
Herança
Hello
public class Hello extends Thread{
public void run() {
System.out.println("Hello world!");
}
}

Alo
public class Alo extends Thread{
public void run() {
System.out.println("Alo mundo!");
}
}

Universidade Católica de Brasília


Ciência da Computação
Herança
Principal
public class Principal {

public static void main(String[] args) {


Hello hello = new Hello();
hello.start();

Alo alo = new Alo();


alo.start();
}
}

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Testar a aplicação

Universidade Católica de Brasília


Ciência da Computação
Runnable versus herança de Thread

• Qual dessas opções você deve usar?


• A primeira opções, que emprega um objeto Runnable, é mais geral,
porque o objeto Runnable pode criar uma subclasse de uma classe
diferente de Thread.
• A segunda opção é mais fácil de usar em aplicativos simples, mas é
limitada pelo fato de que sua classe de tarefa deve ser descendente
de Thread.
PARALELISMO EM JAVA

Principais métodos:
 Construtores: Thread(), Thread (Runnable), Thread(String),
Thread(Runnable, String)...
 Nome da Thread:
 Identificador não-único.
 Pode ser definido ao criar a Thread
 Se não for definido o nome será "Thread-n" (n incremental)
 Pode ser redefinido com setName(String)
 Pode ser obtido através do método getName()

Universidade Católica de Brasília


Ciência da Computação
Criando e nomeando a thread
public class Principal {
public static void main(String[] args) {

Thread hello = new Thread(new Hello(),"t1");


hello.run();
System.out.println("criou: " + hello.getName());

Thread alo = new Thread(new Alo(),"t2");


alo.run();
System.out.println("criou: "+alo.getName());
}
}
PARALELISMO EM JAVA

Testar a aplicação

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Outros métodos:
 Obter referência da thread em execução: currentThread()
 Suspender execução: sleep(long), interrupt()
 Aguardar fim da thread: join(), join(long)
 Verificar estado: isAlive(), isInterrupted()
 Liberar o processador: yield()
 Destruir a thread: destroy()

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Obtendo o id da thread dentro dela:


public class Hello extends Thread{
public void run() {
System.out.println("Hello world!");
Thread t = Thread.currentThread();
System.out.println(t.getName());
}
}
PARALELISMO EM JAVA

• Testar a aplicação:
• Adapte sua aplicação para
mostrar os nomes das
threads.

Universidade Católica de Brasília


Ciência da Computação
import java.util.List;
Outras formas de lançar import java.util.ArrayList;

uma Thread public class lambdaHello {


public static void main(String[] args) {
String user1 = "João da Silva";
String user2 = "Manoel Pereira";

• Expressões Lambda String user3 = "Maria do Carmo";

com passagem de List<String> users = new ArrayList<>();


users.add(user1);

parâmetros: users.add(user2);
users.add(user3);
sayHelloMultipleUsers(users);
• A sintaxe geral para usar }
private static void sayHelloMultipleUsers(List<String> users) {
expressões lambda é: HelloWorld helloworld = new HelloWorld();
users.forEach((user)-> {
• (Parâmetros) -> Thread thread = new Thread(()-> helloworld.sayHello(user), user);
{Corpo} thread.start();
});
• onde -> separa os }
}
parâmetros e o public class HelloWorld {
corpo da expressão public void sayHello(String user) {
System.out.println("Hello "+user);
lambda. Thread t = Thread.currentThread();
System.out.println("nome da thread: " + t.getName());

}
}
PARALELISMO EM JAVA

• Testar a aplicação:
• Adicione mais usuários

Universidade Católica de Brasília


Ciência da Computação
Outras formas de lançar uma Thread

public class calcparalela {


public static void main(String[] args) {
Calculadora calc = new Calculadora();
Outro exemplo: Thread c1 = new Thread( () -> calc.add(1,2));
Thread c2 = new Thread( () -> calc.add(3,4));
c1.start();
c2.start();
}
static class Calculadora{
public int add(int a, int b) {
int c = a+b;
System.out.println(a + "+" + b + "=" + c);
return c;
}
}
}
PARALELISMO EM JAVA

• Testar a aplicação:
• Adicione uma operação de
multiplicação na calculadora

Universidade Católica de Brasília


Ciência da Computação
Criando threads para executar um bloco de código

• Nesse exemplo criamos as threads


passando um bloco de código
public class ThreadExample {

public static void main(String[] args){


System.out.println(Thread.currentThread().getName());
for(int i=0; i<10; i++){
new Thread("" + i){
public void run(){
System.out.println("Thread: " + getName() + " running");
}
}.start();
}
}
}
PARALELISMO EM JAVA

• Testar a aplicação:
• Insira uma pausa de um segundo entre cada lançamento de
thread
• Thread.sleep(1000L);
• Mostre dentro da thread o instante de tempo:
• System.out.println(“Agora: " +
ZonedDateTime.now().toInstant().toEpochMilli());

Universidade Católica de Brasília


Ciência da Computação
Controle de execução

• Existem diversas maneiras de controlar a execução de uma thread:


 Suspender execução: sleep(long), interrupt()
 Aguardar fim da thread: join(), join(long)
 Verificar estado: isAlive(), isInterrupted()
 Liberar o processador: yield()
 Destruir a thread: destroy()
 Com um objeto Runnable a thread principal pode chamar métodos
das threads criadas por ele. Veja o exemplo:
Controle de execução
public class MyRunnable implements Runnable { public class MyRunnableMain {
private boolean doStop = false; public static void main(String[] args) {
public synchronized void doStop() { MyRunnable myRunnable = new MyRunnable();
this.doStop = true; Thread thread = new Thread(myRunnable);
} thread.start();
private synchronized boolean keepRunning() { try { Thread.sleep(10L * 1000L); }
catch (InterruptedException e) {
return this.doStop == false;
e.printStackTrace();
}
}
@Override myRunnable.doStop();
public void run() { }
while(keepRunning()) { }
// keep doing what this thread should do.
System.out.println("Running");
try {
• Nesse exemplo a thread principal
Thread.sleep(3L * 1000L); interrompe a thread filho após 10
} catch (InterruptedException e) {
e.printStackTrace(); segundos
}
}
}
}
PARALELISMO EM JAVA

• Testar a aplicação:
• Adapte o código de forma que a thread filho
imprima uma mensagem a cada 1 segundo
com um contador de quantas segundos se
passaram.

Universidade Católica de Brasília


Ciência da Computação
Esperando a thread acabar
public class MyRunnable implements Runnable { public class MyRunnableMain {
private boolean doStop = false; public static void main(String[] args) {
public synchronized void doStop() { MyRunnable myRunnable = new MyRunnable();
this.doStop = true; Thread thread = new Thread(myRunnable);
} thread.start();
private synchronized boolean keepRunning() { while(thread.isAlive()) {
System.out.println("Thread is alive");
return this.doStop == false;
try { Thread.sleep(1000L); }
}
catch (InterruptedException e) {
@Override e.printStackTrace();
public void run() { }
for(int i=0;i<10;i++) { System.out.println("Thread is dead");
// keep doing what this thread should do. }
System.out.println("Running"+i); }
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
Nesse o controle fica do lado da
}
e.printStackTrace(); thread.
} Note que a thread principal espera
}
} o filho acabar
PARALELISMO EM JAVA

• Testar a aplicação:
• Adapte o código de forma que a thread filho
continue imprimindo uma mensagem a cada 1
segundo com o contador mas por 20 segundos
• O programa principal deve esperar por 10
segundos testando se a thread está viva mas
depois disso deve terminar a thread filho

Universidade Católica de Brasília


Ciência da Computação
PROGRAMAÇÃO PARALELA

Perguntas?
Universidade Católica de Brasília
Ciência da Computação
Obrigado!!!

Universidade Católica de Brasília


Ciência da Computação
PARALELISMO EM JAVA

Atividade!

Universidade Católica de Brasília


Ciência da Computação
Atividade

• Implemente um programa em Java que lance 5 threads, cada uma com


prioridades diferentes (1 a 5) e nomes diferentes
• Elas devem imprimir uma mensagem a cada 3 segundos mostrando o
timestamp do instante atual e seu id
• Cada vez que imprimirem a mensagem elas devem obter um número
randômico inteiro entre 0 e 1000 e testar se o resto da divisão desse
número por 5 é zero. Se for a thread deve encerrar.
• O programa principal deve testar a cada 5 segundos quais threads ainda
estão vivas e mostrar na tela
• Após 30 segundos o programa deve parar as 5 threads ainda vivas

Você também pode gostar