Unidade 1-1: Introdução
Unidade 1-2: Processos
e Threads
Tarefa 1-2
Unidade 1-3: Programação com Threads
Material de Apoio de outros links sobre threads:
O que é um thread?
O ciclo de vida de um thread
Estados e
Métodos Básicos de uma Thread
Cap. 23-Deitel: Java Como Programar, Ed.6
Ciclo de Vida de
uma Thread, Métodos executados por threads.
Prioridades de
Threads
Veja em
Capitulo-23-Deitel-Java-Como-Programar-6-Edicao.pdf
Primeiro Exemplo Básico de Programação com Threads em Java
Mas,
antes, analise o exemplo Deitel-Cap 15-Ed.4, mais simples, 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
Neste exemplo inicial,
a
classe Thread serve para criar novas classes que
suportam multithreading. O método run() da classe Thread deve
ser sobrescrito 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
Segundo Exemplo Básico de Programação com Threads em Java
Implementação de um Thread (classe Thread e 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
Exemplos de Threads de Temporização:
Uso das classes Timer e TimerTask
Escalonamento de Threads
Criando um pool de número fixado de threads:
Um pool de threads é uma coleção de threads que podem ser
fixadas, que são escalonadas pelo processador, para executarem tarefas
(programadas em threads) que requisitam execução.
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).
Cap. 23-Deitel: Java Como Programar, Ed.6
Ciclo de Vida de
uma Thread, Métodos executados por threads.
Prioridades de
Threads
Veja em
Capitulo-23-Deitel-Java-Como-Programar-6-Edicao.pdf
Você pode ver os seguintes links:
Pool de Threads
Java Threading: the Executor Framework
(Um melhor mecanismo para executar threads em Java.)
Grupo de Threads
Sincronização de Threads
Exemplos para Escalonamento de Threads
em Diferentes Formas
-------------------------------------------------------------------------------------------
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 ???
Monitores
Explicação do Problema dos
Leitores e Escritores
Pseudo-Código:
Leitores e Escritores (para entendimento do problema)
Laboratório 1: Threads
e Monitores
--------------------------------------------------------------------------------------------
Unidade 2 - Sincronização com Locks
Controle de Concorrência com Locks (slides
com aplicação à transações)
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.
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
Locks
Explícitos e Variáveis de Condição
Explicando Locks com o método trylock()
Laboratório 2:
Problema da
Janta dos Filósofos (17/04/2012)
-------------------------------------------------------------------------------------------
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 (30/04/2012)
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 de Métodos
Tarefa 5.2 - Questionário:
Objetos Distribuídos e Invocação Remota
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 - 12/06/2012
Prova 2 - Com
respostas
Prova de Recuperação: 10/07/2012
------------------------------------------------------------------------------------------- |