Execução concorrente usando Semaphore

3 respostas
G

Boa noite pessoal.
Estou aqui mais uma vez para, se possível, vocês me ajudarem a solucionar um problema.
Tenho um código, o famoso contaCorrente, e preciso acabar com as inconsistências usando a classe Semaphore.
O problema é que não entendi como ela funciona e não sei como fazer.
o código é este:

class Conta extends Thread {
public double saldo = 0;
public Conta(double saldo) {
this.saldo = saldo;
System.out.println("Conta criada. Saldo inicial: R$" + saldo);
}
public double getSaldo() {
return saldo;
}
public void setSaldo(double saldo) {
this.saldo = saldo;
}
}

class Banco extends Thread{
public boolean saque(Conta conta, double valor) {
double saldo = conta.getSaldo();
if (saldo < valor) {
System.out.println("Saldo insuficiente para o saque.");
return false;
}
double novoSaldo = saldo - valor;
System.out.println(Thread.currentThread().getName() + " sacou R$"+valor+". Saldo após saque: R$"+novoSaldo);
conta.setSaldo(novoSaldo);
return true;
}
}

public class Cliente extends Thread {
private static Banco banco = new Banco();
private Conta conta = null;
private double valor = 100;
public Cliente(String nome, Conta conta) {
super(nome);
this.conta = conta;
}
public void run() {
double total = 0;
while (banco.saque(conta,valor))
total += valor;
System.out.println(getName() + " sacou total de R$" + total);
}
}

class Familia {
public static void main (String args[]) {
// Cria conta conjunta da família
final Conta conta = new Conta(100000);
// Cria familiares e lhes informa a conta conjunta
Cliente pai = new Cliente("Pai ", conta);
Cliente mae = new Cliente("Mãe ", conta);
Cliente filho = new Cliente("Filho", conta);
// Inicia as threads
pai.start();
mae.start();
filho.start();
}
}

Está havendo muita inconsistência na saída dos dados...

Se puderem me ajudar...

3 Respostas

A

Vc não está usando nenhum tipo de controle (semáforo) nesta classe . Vc poderia usar um método synchronize ou então um bloco synchronize.

public boolean saque(Conta conta, double valor) {
synchronize {  
           double saldo = conta.getSaldo();  
           if (saldo < valor) {  
                System.out.println("Saldo insuficiente para o saque.");  
                return false;  

      } 

        double novoSaldo = saldo - valor;  
        System.out.println(Thread.currentThread().getName() + " sacou R$"+valor+". Saldo após           saque: R$"+novoSaldo);  
        conta.setSaldo(novoSaldo);  
        return true;  
}
}
G

Vc não está usando nenhum tipo de controle (semáforo) nesta classe . Vc poderia usar um método synchronize ou então um bloco synchronize.

public boolean saque(Conta conta, double valor) {

Obrigado alexmonassa…
Mas eu preciso resolver isso com o semaphore…rsrsrsr
E pra falar a verdade eu não entendi muito bem como o semaphore funciona. Se você puder me explicar vai ser de grande ajuda.

Obrigado.

A

Bem o semaforo funciona da seguinte forma: dois processos querem acessar o mesmo metodo , só um deles pode por vez , usando semáforo vc regula quem pode usar por quanto tempo e libera o uso para o outro processo.

No seu caso vc poderia usar o synchronized ou o bloco synchronized das partes criticas do sistema.

ficaria assim:
public synchronized boolean saque(Conta conta, double valor) {
        double saldo = conta.getSaldo();


        if (saldo < valor) {
            System.out.println("Saldo insuficiente para o saque.");
            return false;
        }
        double novoSaldo = saldo - valor;
        System.out.println(Thread.currentThread().getName() + " sacou R$" + valor + ". Saldo após saque: R$" + novoSaldo);
        conta.setSaldo(novoSaldo);
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
        }
Criado 6 de abril de 2014
Ultima resposta 8 de abr. de 2014
Respostas 3
Participantes 2