Olá galera!
gostaria de saber se alguém aqui já usou, ou rodou algum exemplo/código
que gerasse algum deadlock em threads…
Valeus!!!
Olá galera!
gostaria de saber se alguém aqui já usou, ou rodou algum exemplo/código
que gerasse algum deadlock em threads…
Valeus!!!
Já vi exemplos… 
sim … mas tem como vc postar pra gente discutir???
Exemplo Clássico:
public class Caixa {
double saldoCaixa = 0.0;
Cliente clienteDaVez = null;
public synchronized void atender(Cliente c, int op, double v) {
while (clienteDaVez != null) {
wait();
} //espera vez
clienteDaVez = c;
switch (op) {
case -1:
sacar(c, v);
break;
case 1:
depositar(c, v);
break;
}
}
private synchronized void sacar(Cliente c, double valor) {
while (saldoCaixa <= valor) {
wait();
} //espera saldo, vez
if (valor > 0) {
saldoCaixa -= valor;
clienteDaVez = null;
notifyAll();
}
}
private synchronized void depositar(Cliente c, double valor) {
if (valor > 0) {
saldoCaixa += valor;
clienteDaVez = null;
notifyAll();
}
}
}
Onde está o deadlock?
Cenário 1:
Saldo do caixa: R$0.00
Cliente 1 (thread) é atendido (recebe acesso do caixa),
deposita R$100.00 e libera o caixa
Cliente 2 (thread) é atendido (recebe o acesso do caixa),
saca R$50.00 e libera o caixa
Cenário 2: cliente 2 chega antes de cliente 1
Saldo do caixa: R$0.00
Cliente 2 é atendido (recebe acesso do caixa), tenta sacar
R$50.00 mas não há saldo. Cliente 2 espera haver saldo.
Cliente 1 tenta ser atendido (quer depositar R$100.00)
mas não é sua vez na fila. Cliente 1 espera sua vez.
DEADLOCK!
Estou vendo a cadeira de SO na faculdade e achei esse um exemplo bastante interessante e de facil entendimento !!!
:?: COMO RESOLVER? :twisted:
VAMU DISCUTIR!!! :razz:
Fábio,
Pelo que entendo, deadlock acontece quando segmentos estão bloqueados aguardando a liberação de bloqueios uns dos outros.
No seu exemplo apenas um segmento detém o bloqueio e não fica aguardando que outro segmento o libere. :oops:
À seguir, um exemplo que adaptei do livro da Kathy:
package teste;
public class Teste {
public static void main(String[] args) {
Recurso rc = new Recurso();
Thread01 t1 = new Thread01(rc);
Thread02 t2 = new Thread02(rc);
t1.start();
t2.start();
}
}
class Thread01 extends Thread {
private Recurso rc;
public Thread01(Recurso rc) {
this.rc = rc;
}
public void run() {
rc.setValores(100, 200);
}
}
class Thread02 extends Thread {
private Recurso rc;
public Thread02(Recurso rc) {
this.rc = rc;
}
public void run() {
rc.getValores();
}
}
class Recurso {
private Dispositivo ds1 = new Dispositivo();
private Dispositivo ds2 = new Dispositivo();
public void setValores(int x, int y) {
synchronized (ds1) {
ds1.setValor(x);
try {
Thread.sleep(1000);
}
catch (InterruptedException e ) {}
synchronized (ds2) {
ds2.setValor(y);
}
}
}
public void getValores() {
synchronized (ds2) {
System.out.println("O valor de ds2 é " + ds2.getValor());
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {}
synchronized (ds1) {
System.out.println("O valor de ds1 é " + ds1.getValor());
}
}
}
}
class Dispositivo {
private int valor;
public void setValor(int x) {
valor = x;
}
public int getValor() {
return valor;
}
}
fabiostb manda ai o metodo main … pra gente ve se ocorre Deadlock.
No exemplo q o robson mandou … o deadlock rolou fica travado o processamento …
Seria como se elas entrassem em disturbio hehehehe
uma esperando a outra … soh q ninguem eh capaz de liberar primeiro …
cara segue ai o codigo q eu ja testei, esse metodo main foi eu quem fez seguindo a ideia dos cenarios, como eu citei anteriormente, porem agora o nobre amigo Robson me deixou na duvida se esse meu exemplo é um deadlock. Nesse exemplo coloquei uma thread startando logo em seguida da outra, acho q isso n garante 100% q vai haver deadlock, pois as thread podem, por sorte do azar, começar no sentido inverso por algum motivo/decisão do escalonador.
Para ter mais segurança q vai ter deadlock é só por os dois clientes dentro de um laço, tentando sacar e depositar infinitamente, assim q um q ta tentando sacar tentar tirar um valor maior do q tem na conta a parada entra em deadlock e o troxo todo morre, pois para o JOAO poder depositar a grana, a rasgada da MARIA tem q deixa o atendimento, e isso num ocorre nunca (nesse caso) pq MARIA foi dormir e deixou o JOAO na fila pra sempre. DESGRACADA :oops: - acho q é por ai
OBS.: FIZ ALGUNS AJUSTE, COLOCANDO UMAS IMPRESSÕES NO CONSOLE SOBRE O Q EXATAMENTE JOAO E MARIA ESTAO FAZENDO, PRA FACILITAR A ANALISE, VISTO Q É FODA, ou talvez impossivel, DEPURAR THREADs
public class Teste2 {
double saldoCaixa = 0.0;
Cliente clienteDaVez = null;
public synchronized void atender(Cliente c, int op, double v) {
System.out.println(c.getNome() + " está tentando ser atendido(a)");
while (clienteDaVez != null) {
try {
System.out.println(c.getNome() + " NÃO foi atendido(a). FOI DORMIR");
wait();
} catch (InterruptedException e) {
}
} //espera vez
System.out.println(c.getNome() + " foi atendido(a)");
clienteDaVez = c;
switch (op) {
case -1:
sacar(c, v);
break;
case 1:
depositar(c, v);
break;
}
}
private synchronized void sacar(Cliente c, double valor) {
System.out.println(c.getNome() + " está tentando sacar");
while (saldoCaixa <= valor) {
try {
System.out.println(c.getNome() + " não conseguiu sacar. SALDO INSUFICIENTE!. FOI DORMIR");
wait();
} catch (InterruptedException e) {
}
} //espera saldo, vez
if (valor > 0) {
saldoCaixa -= valor;
clienteDaVez = null;
notifyAll();
}
}
private synchronized void depositar(Cliente c, double valor) {
System.out.println(c.getNome() + " está tentando depositar");
if (valor > 0) {
System.out.println(c.getNome() + " conseguiu depositar");
saldoCaixa += valor;
clienteDaVez = null;
notifyAll();
}
}
public static void main(String args[]) {
final Teste2 caixa = new Teste2();
Cliente cliente2 = new Cliente("Maria") {
public void run() {
caixa.atender(this, -1, 50);
}
};
cliente2.start();
Cliente cliente1 = new Cliente("João") {
public void run() {
caixa.atender(this, 1, 100);
}
};
cliente1.start();
}
}
class Cliente extends Thread {
private String nome;
Cliente(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
}
Esse lance de concorrencia, condicao de corrida, deadlock, semaforos é um assunto muito rico e se quisermos complicar n teremos trabalho :roll: ! tudo feito com threads tem de ser feito com muito cuidado e analise :???: [/code]