Threads[RESOLVIDO]

7 respostas
renansrr

Olá pessoal sou novo ak no forum, seguinte eu preciso fazer um programa que tenha duas Threads onde uma Thread vai somar um valor a variável compartilhada e a outra vai subtrair um valor por ex: váriavel compartilhada x = 10, Thread1 soma 10 a x, Thread2 subtrai 10 a x, de forma que o valor de x iniciado com 10 não mude ou seja, vo precisar sincronizar o acesso a essa váriavel ai é que ta o X da questão não estou conseguindo fazer a sincronização, já tentei syncronized, semaphore mas ainda não consegui resultado espero que possam me ajudar com exemplos =).

7 Respostas

renansrr

Nem uma ajuda =/

Vini_Fernandes

Cara, veja o seguinte exemplo sobre saque/deposito em uma conta corrente:

Classe para teste:

public class Teste{
	public static void main(String [] asdf){
		ContaCorrente cc = new ContaCorrente(10000.00f, 999);
		
		Cliente c1 = new Cliente("Vinicius",1234,cc);
		Cliente c2 = new Cliente("Marcos",4321,cc);
		
		c1.cc = cc;
		c2.cc = cc;
		
		Saque s1 = new Saque(c1, cc, 20f);
		Saque s2 = new Saque(c2, cc, 220f);
		Thread t1 = new Thread(s1, c1.nome);
		Thread t2 = new Thread(s2, c2.nome);
		
		t1.start();
		t2.start();
	}
	
}

Classe para efetuar os saques

public class Saque implements Runnable{
	Float valor ;
	Cliente cliente;
	ContaCorrente cc;
	public Saque(Cliente cliente, ContaCorrente cc, Float valor){
		this.cliente=cliente;
		this.cc=cc;
		this.valor = valor;
		
	}
	
	public void run(){
		synchronized(cliente){
			System.out.println("Cliente "+cliente.nome+" vai sacar:");
			Float saldo = cc.getSaldo() ;
			if(saldo > 0 && valor <= saldo)
				Operacao.SACAR.realizarOperacao(cc, valor);
			System.out.println("Cliente sacou!");
		}
	}
}

Tipo Enum para realizar as operacoes

public enum Operacao{
	SACAR{
		public synchronized void realizarOperacao(Cliente cliente, Float quantia){
			System.out.println("Cliente "+cliente.nome+" sacando: ");
			cliente.cc.setSaldo(cliente.cc.getSaldo()-quantia);
			System.out.println("Cliente "+cliente.nome+" terminou o saque: ");
		}
	},
	DEPOSITAR{
		public  void realizarOperacao(Cliente cliente, Float quantia){
			cliente.cc.setSaldo(cliente.cc.getSaldo()+quantia);
		}
	};
	
	Operacao(){}
	
	public  abstract void realizarOperacao(Cliente cliente, Float quantia);
}

Classe que modela o Cliente

public class Cliente implements Comparable<Cliente>{
	public String nome; 
	public Integer documento;
	public ContaCorrente cc;
		
	public Cliente(String n, Integer d, ContaCorrente c){
		nome = n;
		documento = d;
		cc = c;
	}
	
	public int compareTo(Cliente c){
		return c.nome.compareTo(nome);
	}
	
	public boolean equals(Object o ){
		if(o == null)
			return false;
		else if (o instanceof Cliente && ((Cliente)o).documento.equals(this.documento))
			return true;
		
		return false;
	}
	
	public int hashCode(){
		return documento;
	}
	
	public String toString(){
		return this.nome+":"+this.documento;
	}
}

Classe que modela a conta corrente

public class ContaCorrente {
	private final Integer numero;
	private Float saldo;
	//public Set<Cliente> clientes;
	
	public ContaCorrente(Float s, Integer n){
		numero = n;
		saldo = s;
	}
	
	public Float getSaldo(){
		return saldo;
	}
	
	public void setSaldo(Float valor){
		saldo = valor;
	}
	
	public Integer getNumero(){
		return numero;
	}
}

ate mais

daniellfeijo

Será que é isso que vc quer?

package br.com.daniel.threads.contas;
/**
 * Classe que vai possuir um atributo estático que vai
 * ser usado nas classes filhas.
 * 
 * @author Daniel
 *
 */
public abstract class ValorBase {
	/**
	 * Atributo que vai ser usado pelas Threads
	 */
	private static int x =10;
	/**
	 * 
	 * @param valor que vai ser o novo valor de x
	 */
	public static synchronized void adicionaValor(int valor){
		ValorBase.x += valor;
	}
	public static synchronized int getValor(){
		return ValorBase.x;
	}

}
package br.com.daniel.threads.contas;
/**
 * Classe que vai ser o primeiro thread
 * 
 * @author Daniel
 *
 */
public class Calculo1 extends ValorBase implements Runnable{
	public void run(){
		ValorBase.adicionaValor(-10);
		System.out.println(ValorBase.getValor());
	}

}
package br.com.daniel.threads.contas;
/**
 * Classe que vai ser o segundo thread
 * 
 * @author Daniel
 *
 */
public class Calculo2 extends ValorBase implements Runnable {
	public void run(){
		ValorBase.adicionaValor(+10);
		System.out.println(ValorBase.getValor());
	}

}
package br.com.daniel.threads;
import br.com.daniel.threads.contas.*;
/**
 * Classe com metodo main para testar as threads
 * 
 * @author Daniel
 *
 */
public class TesteThreads {
	public static void main(String [] args){
		//Criando os objetos
		Calculo1 c1 = new Calculo1();
		Calculo2 c2 = new Calculo2();
		//Criando as Threads
		Thread t1 = new Thread(c1);
		Thread t2 = new Thread(c2);
		//Rodando os Threads
		t1.start();
		t2.start();
		//Vendo o resultado
	}

}

Será que é isso que vc queria? Acho que foi isso que entendi…

Abraço…

renansrr

obrigado pela ajuda era quase isso mesmo, so que preciso syncronizar o acesso, por ex; A Thread1 soma 10, ai a Thread2 so poderia subtrair depois que o recurso fosse liberado para não haver inconsistencia mas des de já obrigado pela ajuda.

daniellfeijo

isso… mas foi isso que fiz no meu codigo… usei o synchronized justamente para isso…

Bom… fico feliz se ajudei de alguma forma…

Abraço…

renamed

renansrr

poste o q vc fez ai e nos aponte sua duvida!

renansrr

Obrigado amigos pela ajuda, tendo duvidas postarei + ^^.

Criado 8 de novembro de 2009
Ultima resposta 9 de nov. de 2009
Respostas 7
Participantes 4