Unidade 1:
Introdução 2011
Unidade 2-Parte 1:
Programação Concorrente
Material de Apoio: Cap. 15-Deitel: Java Como Programar, Ed.4
Ciclo de Vida de
uma Thread, Métodos executados por threads.
Prioridades de
Threads
Analisar o exemplo, sobre a estruturação de threads, executando
adormecimento e despertar de threads, usando
herança direta da classe Thread. Os arquivos abaixo contém texto e código
explicativo.
Tarefa Inicial de Programação - Estruturação de
Threads 15.4 Ed 4
A classe Thread serve para criar novas classes que
suportam multithreading. Sobrescrevemos o método run() para programar
as tarefas que serão realizadas concorrentemente.
Porém, se precisamos suportar multithreading em uma classe que já
é herdada (derivada) de uma classe diferente da classe Thread, a
estruturação de threads é feita implementando-se a interface Runnable
nessa classe, porque Java não permite que se herde mais de uma classe ao
mesmo tempo. A própria classe Thread implementa Runnable (interface
no pacote (java.lang), como no exemplo:
public class Thread extends Object implements
Runnable
Analisar um
exemplo, sobre a estruturação de threads, executando o adormecimento e
despertar de threads, usando a interface Runnable.
Tarefa Inicial de Programação - Estruturação de Threads
com Runnable. 23.4 Ed 6
Criando um pool de número fixado de threads:
Um pool de threads é uma coleção de threads disponíveis
para realizar tarefas.
Para um grande número de threads, um
pools de threads, geralmente provêem:
- Um programa com muitas threads pode sofrer em desempenho.
- Melhor performance quando se executam um grande número de threads.
Para usar pools de threads, instancie uma implementação da interface
ExecutorService e entregue tarefas para execução.
Essa implementação da interface ExecutorService permite que você estabeleça
entre outras coisas:
- O número básico e máximo do pool (número de threads).
- Como criar e terminar threads.
- Como tratar tarefas rejeitadas, isto é, sem poderem ser executadas
porque todas as threads no pool estão em uso. Pode-se usar um número
fixo de threads e com menos threads do que tarefas.
O método
newFixedThreadPool(int) da
classe Executors, cria um pool com número fixo de threads e
fila ilimitada de tarefas.
No exemplo 23-5, threads são utilizadas por um objeto threadExecutor
da interface ExecutorService. Desta forma os Runnables
que implementam as threads, são executados.
No caso de haver um número fixo de threads, com menos threads do que
tarefas, se o método Execute for chamado e todas as threads em
ExecutorService (interface para gerenciar threads) estiverem em uso,
a tarefa (implementada em Runnable) será colocada numa fila e
atribuído à primeira thread que completar sua tarefa.
Interfaces e Classes usadas:
interface Runnable,
interface Executor,
interface ExecutorService, para gerenciar threads em um pool de threads.
classe Executors (com s no final
é uma classe).
Unidade 2-Parte 2:
Concorrência em Java
Para se aprofundar, você pode ver os seguintes links:
Pool de Threads
Java Threading: the Executor Framework
Um melhor mecanismo para executar threads em Java.
-------------------------------------------------------------------------------------------
Unidade 3:
Controle de
Concorrência
Sincronização de Threads
Inanição = Starvation
Tarefa
Inicial de Programação 3.1 - Produtor-Consumidor com Monitor.
Livro "Java Como Programar", Edição 6, Deitel & Deitel -
Cap. 23 - Multithreading
Download de códigos do livro Deitel, Java: Como Programar Ed. 6:
http://www.inf.ufsc.br/~bosco/downloads/Java 6 CD/ch23/fig23_6_10/
Você deve procurar os arquivos fig23 6-10, onde 23.6 (Interface Buffer),
23.7 (class Producer) e 23.8 (class
Consumer), que são os exemplos da seção 23.6 (Relacionamento
entre produtor e consumidor sem sincronização).
Analise primeiro, os códigos em 23.9 e 23.10, que tratam da implementação de um buffer
não-sincronizado UnsynchronizedBuffer e do aplicativo de teste SharedBufferTest.
Lembre-se que a corretude do programa é que
a thread Producer execute primeiro e que cada valor produzido por
Producer seja consumido exatamente uma vez pelo Consumer.
No código 23.10, a implementação SharedBufferTest, do
aplicativo produtor-consumidor mostra duas threads que manipulam o buffer
não-sincronizado UnsynchronizedBuffer.
Veja o resultado de sua execução !!!
O que você nota ???
-------------------------------------------------------------------------------------------
Analise, agora, o relacionamento entre produtor e consumidor com
sincronização, veja agora a seção 23.12 sobre Monitores em Java.
Novamente você deve aproveitar os códigos 23.6 do Buffer e as
classes Producer (em 23.7) e Consumer (em 23.8) do exemplo da
seção 23.6.
http://www.inf.ufsc.br/~bosco/downloads/Java 6 CD/ch23/fig23_19_20/
Veja, agora, os códigos em fig23 19-20.
O código que realiza a
sincronização é colocado nos métodos set e get da classe
SynchronizedBuffer (Fig. 23.19), que implementa a interface Buffer. A
explicação do exemplo é importante para o aprendizado sobre monitores. O
código 23.20 SharedBufferTest2 mostra um aplicativo
produto-consumidor que utiliza um buffer sincronizado.
Veja o resultado de sua execução.
O que você nota, agora ???
Explicação do Problema dos
Leitores e Escritores
Pseudo-Código:
Leitores e Escritores (para entendimento do problema)
Laboratório 1: Threads
e Monitores
Para realizar a tarefa do Laboratório 1, convém ver os slides em:
Interfaces e
Classes para Gerenciamento e Escalonamento de Threads
Exemplos para
Escalonamento de Threads
em Diferentes Formas
--------------------------------------------------------------------------------------------
Tarefa Inicial de Programação 3.2 - Produtor-Consumidor com Locks.
Utilizar o mesmo exemplo de código da tarefa anterior sobre monitor e
realizar sincronização usando locks.
Locks
Explícitos e Variáveis de Condição
Relacionamento Produtor-Consumidor com
sincronização usando Locks (Exemplo Deitel 6Ed. Cap. 23, Seção 23.7,
pag. 800-805).
Sobre código reentrante:
Reentrância – É comum, em sistemas
multiprogramáveis, vários usuários executarem os mesmos utilitários do SO
simultaneamente, como, por exemplo, um editor de textos. Se cada usuário que
utilizasse o editor trouxesse o código do utilitário para a memória, haveria
diversas cópias de um mesmo programa na memória principal, o que ocasionaria
um desperdício de espaço.
Reentrância é a capacidade de um código de programa (código reentrante)
poder ser compartilhado por diversos usuários, exigindo que apenas uma cópia
do programa esteja na memória. Uma característica da reentrância é que o
código não pode ser modificado por nenhum usuário no momento em que está
sendo executado.
A reentrância permite que cada usuário
possa estar em um ponto diferente do código reentrante, manipulando dados
próprios, exclusivos de cada usuário.
Os utilitários do sistema, como editores
de texto, compiladores e linkers (linker editors), são exemplos de código
reentrante, que proporcionam grande economia de espaço em memória e aumento
na performance do sistema. Em alguns sistemas existe a possibilidade de
utilizar o conceito de reentrância para aplicações de usuários.
(Reentrância) Um link interessante:
http://www2.eletronica.org/artigos/eletronica-digital/reentrancia
Laboratório
2: Locks
Explicando Locks com o método
trylock()
Exemplo de Implementação Lab 2 (Locks)
Main.java
Estante.java
Professor.java
Estudante.java
Livro.java
BufferMensagem.java
Unidade 3: Controle de Concorrência com Locks (slides
com aplicação à transações)
Tarefa Prática (Opcional):
Implementar a concorrência, usando locks, entre as duas transações T e U
exemplificadas no slide 83. Você pode considerar a implementação de uma
Interface Coordinator de transações, como no slide 37, a Classe Lock e a
Classe LockManager, como mostradas ao final dos slides.
-------------------------------------------------------------------------------------------
Tarefa Inicial de Programação 3.3 - Produtor-Consumidor com Semáforo.
Exemplos de
Produtor-Consumidor com Semáforo:
Montar o segundo exemplo do problema do Produtor-Consumidor com
Sincronização, buffer limitado, da seção 23.12. Mas, usando semáforos
(pacote (java.util.concurrent. Semaphore) Você deve procurar, no link acima,
os arquivos das figuras 23.6 (Interface Buffer), 23.7 (Classe Producer)
e 23.8 (Classe Consumer), do exemplo da seção 23.6. O código que
realiza a sincronização é colocado nos métodos set e get da
classe SynchronizedBuffer (Fig. 23.19), que implementa a
interface Buffer.
O trabalho
poderá ser feito em dupla, mas a dupla deverá estar presente para mostrar o
programa funcionando. Postar a tarefa no Moodle até a data programada, a
aula de terça-feira (16/03). Para quem é iniciante, um exemplo de programa a
ser modificado, está no Cap. 23 do livro referido acima, nas seções . A
explicação do exemplo é importante para o aprendizado sobre semáforos.
Laboratório 3:
Semáforos
-------------------------------------------------------------------------------------------
Material
Semaphore-Monitor (Para estudar para a primeira prova)
Lista
1 (Monitores, Locks e Semáforos)
Responda no arquivo e devolva no Moodle em PDF.
Lista 2
(Equivalência Serial de Transações e Locks)
Prova 1
Prova 1
(com respostas)
-------------------------------------------------------------------------------------------
Unidade 4: Sockets. Ver slides do Prof. Lau
Cap.4 (Coulouris)
Communicação Inter-Processos
Comunicação por Sockets
Programação
com Sockets.
Implementar
uma aplicação distribuída usando sockets.
(1) Comunicação de Datagramas UDP
Exemplo 1: UDPClient1 x
UDPServer1
Exemplo 2: UDPClient2 x
UDPServer2
Exemplo 3: UDPClient3 x
UDPServer3
(2) Comunicação com TCP Streams
Exemplo 2: TCPClient2 x
TCPServer2
(3) Comunicação de grupo com IP Multicast.
API Abstration Multicast
(contém alguns slides sobre Multicast)
Multicasting in Java (contém
explicação sobre Multicast em Java)
Livro de Sistemas Distribuidos (Coulouris)
Laboratório 4.1 (Tarefa
proposta pelo Prof. Bosco):
Tarefas com Sockets
Exemplos de Código para implementação e datagramas com sockets.
Datagram Socket Client
Datagram Socket Server
Exemplos e Código para implementação e sockets TCP
TCP Stream Socket
Client
TCP Stream Socket
Server
Exemplo de código para implementação de comunicação de grupo com multicast
IP.
Group
Communication Socket com IP Multicast
Laboratório 4.2 (Tarefa
proposta pelo Prof. Lau) :
Comunicação por Sockets
-------------------------------------------------------------------------------------------
Unidade 5 - Objetos Distribuidos com Java RMI
Tarefa 5.1 RMI:
Calculadora
(preliminar, feito em aula)
Objetos Distribuídos:
RPC, CORBA, Java RMI
Objetos Distribuídos e Invocação Remota
Tarefa 5.2 - Questionário: Objetos Distribuídos e
Invocação Remota de Métodos
Tarefa 5.3 - Usando o Padrão de Projeto
"Factory"
Laboratório 5.4 (Bosco)
Implementando CallBack
Implementar usando sockets ou Java RMI,
uma aplicação distribuída
sobre o sistema de despertador automático de uma operadora de
telefonia. Um design pattern (padrão de projeto) está descrito no
arquivo texto no link abaixo. Você deve utilizar este design pattern,
podendo se discordar do código usado, refazer conforme seu
entendimento.
Laboratório 5.5 Eventos e
Notificações (Invocação de Métodos Remotos)
Prova 2 - 05/07/2011
Prova de Recuperação: 12/07/2011
------------------------------------------------------------------------------------------- |