concorrência e thread
DESCRIPTION
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 é?. - PowerPoint PPT PresentationTRANSCRIPT
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 Runnablepublic 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 java.io.*; import java.net.*; public class Servidor { public 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); } } }