Concorrência e thread
Petrônio Júnior(pglj)
Márcio Neves(mmn2)
Concorrência


Concorrência ocorre devido à disputa de
recursos compartilhados.
Se dois clientes, por exemplo, tentam alterar
um mesmo objeto, uma inconsistência pode
ser gerada.
Sincronização – o que é?


Em uma aplicação distribuída, vários
computadores com diferentes capacidades de
processamento e diferentes conexões de rede
trabalham em conjunto. Devido a essas
diferenças, eventos que deveriam ocorrer em
determinada ordem são observados fora da
ordem esperada.
Por isso é necessário algum meio de
sincronização.
Alguns problemas com
Concorrência
Não-determinismo:
 x = 1 || x = 2
 Podemos não saber ao certo qual o valor
correto.
Dependência de Velocidade:
 [[ f(); x = 1 ]] || [[ g(); x = 2 ]]
 O valor final de x depende de qual das
funções, f() e g(), terminar primeiro
Alguns problemas com
Concorrência
Starvation:
 Processo de baixa prioridade precisa de um
recurso que nunca é fornecido a ele
Deadlock:
 Dois processos bloqueiam a sua execução
pois um precisa de um recurso bloqueado pelo
outro processo
Como Resolver?






Linguagens de programação geralmente
oferecem primitivas para evitar a ocorrência
desses problemas
Principais recursos para evitar a concorrência:
Eventos
Semáforos
Monitores
Mensagens
Eventos – O que são?




Modelam uma ocorrência do sistema
Primitivas:
wait(x): Espera (bloqueia o processo até) que
ocorra um certo evento “x”
signal(x): Gera uma ocorrência do evento “x”,
reativando todos os processos que foram
bloqueados por um wait anterior.
Semáforos – O que são?



Variáveis que indicam se um recurso está
disponível para uso ou não.
Operações Principais:
initialize(x,n): Inicializa o semáforo “x” e
garante que no máximo “n” processos
utilizarão esse recurso. Se algum outro tentar
utilizá-lo, não será permitido.
Semáforos – O que são?


wait(x): Obtém um recurso do semáforo “x”. Se
nenhum estiver disponível, o processo é
bloqueado
signal(x): Libera um recurso do semáforo “x”.
Se algum processo estiver bloqueado, ou seja,
se tentou obter certo recurso e este não estava
disponível causando o seu bloqueio, então
esse processo será liberado e autorizado a
usar o recurso.
Monitores – O que são?



Apenas um processo pode executar funções
em um determinado momento
Em Java temos o modificador synchronized.
Esse modificador faz com que um objeto que
está sendo acessado só possa ser acessado
novamente quando a tarefa que está sendo
realizada sobre ele seja concluída.
Mensagens – O que são?





Define mensagens que são enviadas entre processos.
Essas mensagens podem ser síncronas ou
assíncronas.
Primitivas:
Send(x,p): Envia a mensagem “x” para o processo p.
Receive(x): Espera até que uma mensagem “x” esteja
disponível
Test(): Verifica se existe uma mensagem disponível
Thread


Um thread é um fluxo único de controle
sequencial dentro de um programa
É uma forma de um processo dividir a si
mesmo em tarefas que passam a dividir o
tempo que ele tem pra ser executado,
executando, dessa forma, “simultaneamente”.
Thread

Um thread não é um programa, mas executa
dentro de um programa.
Thread



O overhead causado pelo thread é menor que
o do escalonamento de processos embora a
mesma memória seja compartilhada.
Além da memória, threads compartilham o
estado da informação de processos.
Quanto mais threads mais complicada a
sincronia com a principal (se for requerida)
Thread

Em java, temos duas alternativas para implementar o
recurso de multi-thread:
a) Estendendo da Classe Thread
public class Execucao {
public static void main(String[] args) {
Proc p = new Proc();
p.start();
while (true) { System.out.println("thread main executando");}
}}
class Proc extends Thread {
public void run() {
while (true) {
System.out.println("thread executando");}
}}
Thread
b) Implementando a Interface Runnable
public class Execucao {
public static void main(String[] args) {
Proc p = new Proc();
Thread t = new Thread(p);
t.start();
while (true) { System.out.println("thread main executando"); }
}
}
class Proc implements Runnable {
public void run() {
while (true) {System.out.println("thread executando");}
}
}
Thread


O método main é uma thread e instancia um
objeto p que também é instância de uma
classe que estende de Thread. O método
start() chamado, informa ao escalonador de
thread que coloque na fila de execução a
Thread p.
A thread p não vai executar imediatamente
quando o método start foi chamado, somente
sinaliza o escalonador
Socket

Sockets são interfaces de programação que
estão entre a camada de transportes e a
aplicação. São como portas que possibilitam a
comunicação entre componentes distribuídos,
de aplicações, em uma rede de computadores.
É um tipo de programação necessária para a
criação de sistemas distribuídos como o RMI e
o CORBA.
Socket


Processos em hosts distintos comunicam-se por meio
de envio de mensagens enviadas e recebidas através
de seu socket. Em uma aplicação distribuída pode-se
enviar um fluxo de informações para outra através dos
sockets.
Ao utilizar sockets, o programador deve utilizar o tipo
adequado ao protocolo de transporte utilizado:
protocolo orientado à conexão (confiável) ou protocolo
não orientado à conexão (não confiável), também
conhecido como datagrama.
Socket


A linguagem Java oferece packages para a programação com
Sockets e para a programação através de invocação remota
de
métodos
ou
RMI
(Remote
Method
Invocation).Entretanto, também temos implementações de
RPC e de Sockets para outras linguagem, como o CORBA
(implementação do RPC para varias linguagens).
Exemplo de uma aplicação Java que utiliza a
programação em Socket para estabelecer uma
conexão e enviar uma mensagem pela rede. Utiliza a
arquitetura Cliente-Servidor.
Socket – Classe Servidor




import
import
public
public
java.io.*;
java.net.*;
class Servidor {
static void main(String[] args) throws IOException {



final String mensagem = "Oi! Tudo bem?";



















ServerSocket socketServidor = new ServerSocket(8080);
// criacao do socket no servidor
System.out.println ("Servidor ativado. Aguardando na porta 8080...\n");
Socket socketCliente = socketServidor.accept( );
// servidor aguarda cliente
OutputStream fluxoSaiSocket = socketCliente.getOutputStream( );
// define fluxo de saida
PrintWriter saida = new PrintWriter(fluxoSaiSocket, true);
InputStream fluxoEntSocket = socketCliente.getInputStream( );
// define fluxo de entrada
BufferedReader entrada = new BufferedReader(new InputStreamReader(fluxoEntSocket));
String msgRecebida = entrada.readLine( );
// recebe mensagem do
cliente
System.out.println ("Mensagem Recebida: <" + msgRecebida + ">");
saida.println(mensagem);
// envia mensagem
para o cliente
System.out.println ("Mensagem Enviada: <" + mensagem + ">\n");
socketCliente.close( );
socketServidor.close( );
saida.close( );
entrada.close( );
}
}
Socket – Classe Cliente





import java.io.*;
import java.net.*;
public class cliente {
public static void main (String[] args) throws IOException {
final String mensagem = "Oi!";






try {
Socket socketCliente = new Socket("localhost", 8080); // criacao do socket no cliente
OutputStream fluxoSaiSocket = socketCliente.getOutputStream( ); // define fluxo de saida
PrintWriter saida = new PrintWriter(fluxoSaiSocket, true);
InputStream fluxoEntSocket = socketCliente.getInputStream( ); // define fluxo de entrada


















BufferedReader entrada = new BufferedReader(new InputStreamReader(fluxoEntSocket));
saida.println(mensagem);
// envia mensagem para o servidor
System.out.println("Mensagem Enviada: <" + mensagem + ">");
String msgRecebida = entrada.readLine( );
// recebe mensagem do servidor
System.out.println ("Mensagem Recebida: <" + msgRecebida + ">\n");
socketCliente.close( );
saida.close( );
entrada.close( );
}
catch(UnknownHostException e) {
System.err.println("Host nao encontrado!");
System.exit(1);
}
catch(java.io.IOException e) {
System.err.println("Conexao nao pode ser estabelecida!");
System.exit(1);
}
Download

Concorr%eancia_e_thread[1][1]