Escolar Documentos
Profissional Documentos
Cultura Documentos
Sincronização de Threads
Introdução
Por enquanto, os threads que vimos são independentes
Os threads não requerem acesso a recursos externos ou a
chamdas de métodos de outros
objetos
Os threads não precisam de preocupar com o que está
ocorrendo com os outros threads
Em outras situação, threads devem compartilhar dados e são
obrigados a se preocupar
com o que os outros estão fazendo
Um exemplo disso é a aplicação chamada "Produtor/Consumidor" em
que um
Produtor produz um fluxo de dados consumidos pelo
consumidor
Por exemplo, um thread (o produtor) poderia estar gravando
dados num arquivo enquanto
outro thread (o consumidor) lê
dados do mesmo arquivo
Outro exemplo: enquanto você digita no teclado, o produtor
coloca eventos de mouse numa
fila de eventos e o consumidor lê
os eventos da mesma fila
Em ambos os casos, temos threads que compartilham um
recurso comum
Com tal compartilhamento, os threads devem se sincronizar
para acessar o recurso
O exemplo Produtor/Consumidor
Um produtor gera um número entre 0 e 9 (a
variável i) e o armazena
num objeto chamado CubbyHole
(um lugarzinho para guardar coisas;
um cubículo)
Para deixar o exemplo mais interessante, o produtor dorme durante
um intervalo
aleatório entre 0 1 100 ms antes de gerar mais números
No programa abaixo, "number" é a identificação do produtor, "i"
é o número gerado
cubbyhole = c;
this.number = number;
cubbyhole.put(number, i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 1/12
05/07/2021 Sincronização de threads
cubbyhole = c;
this.number = number;
int value = 0;
value = cubbyhole.get(number);
...
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 3/12
05/07/2021 Sincronização de threads
...
synchronized {
synchronized(obj) {
Readquirindo um lock
O mesmo thread pode obter um lock que ele já possui sem ter que
esperar
Senão teríamos "deadlock", uma condição de espera
permanente
Veja o exemplo:
public class Reentrant {
b();
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 4/12
05/07/2021 Sincronização de threads
if (available == true) {
available = false;
return contents;
if (available == false) {
available = true;
contents = value;
try {
wait();
} catch (InterruptedException e) { }
available = false;
notifyAll();
return contents;
try {
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 5/12
05/07/2021 Sincronização de threads
wait();
} catch (InterruptedException e) { }
contents = value;
available = true;
notifyAll();
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 6/12
05/07/2021 Sincronização de threads
p1.start();
c1.start();
Eis a saída:
Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Producer #1 put: 3
Consumer #1 got: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
aLock.lock();
try {
try {
condVar.await();
} catch (InterruptedException e) { }
available = false;
contents);
condVar.signalAll();
} finally {
aLock.unlock();
return contents;
aLock.lock();
try {
try {
condVar.await();
} catch (InterruptedException e) { }
contents = value;
available = true;
contents);
condVar.signalAll();
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 8/12
05/07/2021 Sincronização de threads
} finally {
aLock.unlock();
}
import java.util.concurrent.*;
cubbyhole = c;
number = num;
try {
cubbyhole.put(i);
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
O consumidor é semelhante
Para rodar o programa, use ProducerConsumerTest3,
que cria um
ArrayBlockingQueue (implementação de BlockingQueue):
import java.util.concurrent.*;
p1.start();
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 9/12
05/07/2021 Sincronização de threads
c1.start();
Sincronizando coleções
As coleções de Java (ArrayList, ...) não são sincronizadas
Dizemos que o uso dessas coleções não seja "thread-safe"
A exceção é Vector que é sincronizada por motivos históricos
Para criar coleções sincronizadas, você pode criar um decorador da
coleção que
sincroniza os métodos
Java já fornece tais decoradores na classe Collections
Há várias decoradores porque há várias interfaces para usar
coleções
Collection
List
Map
Set
Exemplo: como usar uma lista sincronizada
...
synchronized(list) {
while (i.hasNext())
foo(i.next());
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 10/12
05/07/2021 Sincronização de threads
www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html 12/12