2. Sincronização
Monitores
Construção que pode ser usada para exclusão
mútua e sincronização de processos
Proposto por Dijkstra e posteriormente
implementado por Hoare e Hansen
Explicita e centraliza as sessões críticas em
uma parte especial do código
Exclusão mútua é automaticamente forçada
Facilita o entendimento
Não adota primitivas para demarcar regiões
críticas
Evita o esquecimento do uso das primitivas
Programação Concorrente Glêdson Elias
3. Sincronização
Monitores
Um monitor possui . . .
Nome que tem o propósito de identificação
Variáveis globais que são compartilhadas entre
os processos que usam do monitor
Procedimentos de entrada (procedure entries)
que podem ser ativados pelos processos
Podem possuir variáveis locais e parâmetros
Um único processo poder ativar os
procedimentos do monitor, a cada instante
Impõe a exclusão mútua entre processos
Variáveis globais somente podem ser acessadas
a partir dos procedimentos
Código de inicialização das variáveis globais
Programação Concorrente Glêdson Elias
4. Sincronização
Monitores
monitor: nomemonitor;
declaração de variáveis globais;
procedure operação1(parâmetros);
declaração de variáveis locais;
begin
código que implementa a operação
end;
...
procedure operaçãoN(parâmetros);
declaração de variáveis locais;
begin
código que implementa a operação
end;
begin
código de inicialização das variáveis globais
end
Programação Concorrente Glêdson Elias
5. Sincronização
Monitores x Semáforos
Processo 1 Processo 2 Processo N
S
e Begin Begin Begin
m ... ... ...
á P(s)
Sessão crítica 1
P(s)
Sessão crítica 2
P(s)
Sessão crítica N
f V(s) V(s) V(s)
o ... ... ...
r End; End; End;
o
M
o Begin Begin Begin
n ... ... ...
i oper1(params); oper2(params); operN(params);
t ... ... ...
o End; End; End;
r
Programação Concorrente Glêdson Elias
6. Sincronização
Monitores
Podem ser implementados como uma classe em
linguagens orientadas a objetos
Nome da classe ou instância do objeto
representa o nome do monitor
Atributos representam as variáveis globais
compartilhadas
Métodos representam os procedimentos de
entrada
Construtor representa o código de inicialização
das variáveis compartilhadas
Programação Concorrente Glêdson Elias
7. Sincronização
Monitores em Java
Todo objeto Java possui um monitor associado
Primitiva synchronized permite acessar o
monitor de um objeto
Primitiva pode ser usada em métodos ou
trechos de código (statements)
Assegura que, em um dado instante, apenas um
único thread pode executar métodos do objeto
Thread possui o bloqueio (lock) do monitor do
objeto
Thread está dentro do monitor do objeto
Programação Concorrente Glêdson Elias
8. Sincronização
Monitores em Java
Primitiva synchronized
Métodos Sincronizados
Métodos estáticos também podem ser
sincronizados
Instâncias e classe possuem monitores (locks)
independentes
Cada monitor (objeto / classe), em um dado
instante, permite a execução de um único thread
Trechos de Código Sincronizados
Pode incrementar a concorrência de threads
Permite execução simultânea de diversos
métodos
Programação Concorrente Glêdson Elias
9. Sincronização
Monitores em Java
Dados
O
b Método Fila de processos do
j sincronizado monitor da classe
e Método Fila de processos do
sincronizado monitor do objeto
t
o
Método não
sincronizado Conjunto de processos
sem bloqueio dos monitores
Método não
sincronizado
Programação Concorrente Glêdson Elias
10. Sincronização
Monitores em Java
Métodos Sincronizados
public class SynchClassName {
private String globalVar;
public SynchClassName() {
}
public synchronized void synchMethod() {
String localVar;
}
public void nonSynchMethod() {
}
public static synchronized void synchStaticMethod() {
}
public static void nonSynchStaticMethod() {
}
}
Programação Concorrente Glêdson Elias
11. Sincronização
Monitores em Java
Métodos Sincronizados
public class SynchClass {
public synchronized void synchMethod(int i) {
while (true) System.out.println(i);
}
public void nonSynchMethod(int i) {
while (true) System.out.println(i);
}
public static synchronized void synchStaticMethod(int i) {
while (true) System.out.println(i);
}
public static void nonSynchStaticMethod(int i) {
while (true) System.out.println(i);
}
}
Programação Concorrente Glêdson Elias
12. Sincronização
Monitores em Java
Métodos Sincronizados
public class SynchImpl extends Thread {
int id;
SynchClass sc; public SynchImpl(int id, SynchClass sc) {
... this.id = id;
public void run() { this.sc = sc;
switch (id) { }
case 0:
case 1: sc.synchMethod(id); break;
case 2:
case 3: sc.nonSynchMethod(id); break;
case 4:
case 5: SynchClass.synchStaticMethod(id); break;
case 6:
case 7: SynchClass.nonSynchStaticMethod(id); break;
}
} public static void main (String[] args) {
... SynchClass sc = new SynchClass();
} for (int i=0; i < 8; i++)
(new SynchImpl(i, sc)).start();
}
Programação Concorrente Glêdson Elias
13. Sincronização
Monitores em Java
Trechos de Código Sincronizados
public class SynchClassName {
private String globalVar;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void nonsyncMethod() {
String localVar;
... public void nonsyncMethod1() {
synchronized (this) { synchronized (lock1) {
... ...
} }
... }
}
public void nonsyncMethod2() {
synchronized (lock2) {
...
}
}
Programação Concorrente Glêdson Elias
14. Sincronização
Monitores em Java
Trechos de Código Sincronizados
public class SynchClass {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void synchThisMethod(int i) {
synchronized (this) {
while (true) System.out.println(i);
}
}
public void synchLock1Method(int i) {
synchronized (lock1) {
while (true) System.out.println(i);
}
}
public void synchLock2Method(int i) {
synchronized (lock2) {
while (true) System.out.println(i);
}
}
}
Programação Concorrente Glêdson Elias
15. Sincronização
Monitores em Java
Trechos de Código Sincronizados
public class SynchImpl extends Thread {
int id;
SynchClass sc;
public SynchImpl(int id, SynchClass sc) {
this.id = id;
this.sc = sc; public static void main (String[] args) {
} SynchClass sc = new SynchClass();
for (int i=0; i < 6; i++)
public void run() { (new SynchImpl(i, sc)).start();
switch (id) { }
case 0:
case 1: sc.synchThisMethod(id); break;
case 2:
case 3: sc.synchLock1Method(id); break;
case 4:
case 5: sc.synchLock2Method(id); break;
}
}
...
}
Programação Concorrente Glêdson Elias
16. Sincronização
Monitores em Java
Perigo de Deadlocks
Deve-se tomar cuidado para evitar deadlock
public class BadSynchClass {
private int value;
public synchronized int get() {
return value;
}
public synchronized void set(int i) {
value = i;
}
public synchronized void swap(BadSynchClass bsc) {
int tmp = get();
set(bsc.get()); public BadSynchClass(int v) {
bsc.set(tmp); value = v;
} }
}
Programação Concorrente Glêdson Elias
17. Sincronização
Monitores em Java
Perigo de Deadlocks
public class BadSynchImpl extends Thread {
BadSynchClass a, b;
public BadSynchImpl(BadSynchClass a, BadSynchClass b) {
this.a = a;
this.b = b;
}
public void run() {
a.swap(b);
System.out.println(“A: “ + a.get() + “ B: “ + b.get());
}
public static void main (String[] args) {
BadSynchClass a = new BadSynchClass(1);
BadSynchClass b = new BadSynchClass(2);
(new BadSynchImpl(a, b)).start();
(new BadSynchImpl(b, a)).start();
}
}
Programação Concorrente Glêdson Elias
18. Sincronização
Sincronização com Monitor
Monitor suporta o conceito de sincronização
condicional (conditional synchronization)
Processos esperam que uma dada condição
torne-se verdadeira
Implementada com variáveis de condição
(condition variables)
São usadas para suspender e reativar
processos
São associadas a condições que causam a
suspensão ou reativação de um processo
Possuem duas operações (wait / signal)
Programação Concorrente Glêdson Elias
19. Sincronização
Sincronização com Monitor
x.wait()
Suspende processo chamador e libera monitor
Monitor insere processo suspenso na fila de
espera associada à variável de condição
x.signal()
Reativa processo que está aguardando na fila
associada à variável de condição
Processo reativado retoma a execução do ponto
logo após a chamada do wait
Processo chamador pode ou não liberar monitor
(depende da implementação do monitor)
Programação Concorrente Glêdson Elias
20. Sincronização
Sincronização com Monitor
Reativação de Processos
Monitor Hoare
Processo chamador libera o monitor
Processo reativado inicia execução
Monitor Estilo Java
Processo chamador continua a execução
Processo reativado apenas aguarda a
oportunidade de entrar no monitor
Qual processo deve executar após a
chamada da operação signal?
Programação Concorrente Glêdson Elias
21. Sincronização
Monitor Hoare
Processo da fila executa após a notificação
Permite que o processo notificado inicie sua
execução sem intervenção de outros
processos
Estado no qual o processo inicia a execução é o
mesmo de quando a notificação foi realizada
Processo pode assumir que a condição é
verdadeira após ser reativado
Assume que a notificação é ativada apenas
quando a condição é verdadeira
if (! condition) x.wait();
Programação Concorrente Glêdson Elias
22. Sincronização
Monitor Estilo Java
Processo notificador continua a execução após
realizar a notificação
Processo reativado não pode assumir que a
condição é verdadeira
Notificação é apenas um indicativo de que a
condição pode ser verdadeira
Processo reativado deve explicitamente
reavaliar a condição ao ser reativado
Se a condição for falsa, processo deve ser
suspenso novamente
while (!condition) x.wait();
Programação Concorrente Glêdson Elias
23. Sincronização
Monitores Java
Java não possui variáveis de condição
Todo objeto possui uma única fila de
notificação
Todo objeto suporta as operações wait /
notify / notifyAll
Somente podem ser ativadas por thread que
possui o monitor do objeto
Programação Concorrente Glêdson Elias
24. Sincronização
Monitores Java
Fila de notificação
Dados do objeto
O
b Método Fila de processos do
j sincronizado monitor da classe
e Método Fila de processos do
sincronizado monitor do objeto
t
o
Método não
sincronizado Conjunto de processos
sem bloqueio dos monitores
Método não
sincronizado
Programação Concorrente Glêdson Elias
25. Sincronização
Monitores Java
wait()
Suspende thread chamador e o insere na fila de
notificação do objeto
notify() / notifyAll()
Reativa um único thread (notify) ou todos os
threads (notifyAll) da fila de notificação do
objeto
Thread chamador continua execução e não
libera o monitor
Cada thread reativado é colocado na fila do
monitor do objeto
Programação Concorrente Glêdson Elias