@filipecampos escreveu:
Existem três threads clientes que enviam requisições para cada Objeto Servidor.
Cada Objeto Servidor tem três threads receptoras, cada uma responsável por atender a um cliente distinto. Observem que cada requisição é enviada para todos os três Objetos Servidores através das suas respectivas threads. Esse envio é feito através de um Pipe distinto, não compartilhado. Cada Objeto Servidor possui três métodos: depositar(double valor), retirar(double valor) e aplicarCorrecao(int percentagem), este último faz uma correção monetária sobre o valor
total da conta. Esses métodos são invocados, de forma concorrente, por cada thread no
Objeto Servidor i.O saldo final em cada servidor devem ser iguais e o valor do saldo estão com uma diferença pequena, problema com os piped, as vezes a Thread de deposito realizar o deposto com o valor do saque e vice versa
Cliente Abstrato
package br.com.cliente; import java.io.DataOutputStream; import java.io.IOException; import java.io.PipedOutputStream; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; /** * Classe responsavel por enviar requisições ao servidor * * @author Filipe */ public abstract class AbstractClient extends Thread { //Escritor para servidor 1 protected DataOutputStream out1; //Escritor para servidor 2 protected DataOutputStream out2; //Escritor para servidor 3 protected DataOutputStream out3; protected Random random; protected float value; public AbstractClient(PipedOutputStream pOut1, PipedOutputStream pOut2, PipedOutputStream pOut3) { this.random = new Random(); this.out1 = new DataOutputStream(pOut1); this.out2 = new DataOutputStream(pOut2); this.out3 = new DataOutputStream(pOut3); } /** * Seta o valor da acao a ser escrita */ protected abstract void write(); @Override public void run() { try { for (int i = 0; i < 9; i++) { this.write(out1); this.write(out2); this.write(out3); } //feche os pipeds out1.close(); out2.close(); out3.close(); } catch (IOException ex) { Logger.getLogger(AbstractClient.class.getName()).log(Level.SEVERE, null, ex); } } protected void write(DataOutputStream out) throws IOException { //acao do cliente write(); //cliente dispara acao out.writeFloat(value); try { Thread.sleep(500); } catch (InterruptedException ex) { Logger.getLogger(AbstractClient.class.getName()).log(Level.SEVERE, null, ex); } } /** * Enumerador para indicar qual o servidor deve-se enviar a informação enum Operacao { Server1(1), Server2(2), Server3(3); public final int value; Operacao(int value) { this.value = value; } public static Operacao fromInteger(int x) { switch (x) { case 1: return Server1; case 2: return Server2; default: return Server3; } } }*/ }
Cliente Deposito
package br.com.cliente; import br.com.server.Server; import java.io.PipedOutputStream; /** * Thread para deposito * * @author Filipe */ public class ClientDeposito extends AbstractClient { public ClientDeposito(PipedOutputStream pOut1, PipedOutputStream pOut2, PipedOutputStream pOut3) { super(pOut1, pOut2, pOut3); } @Override protected void write() { this.value = Server.DEPOSITO; } }
Cliente Correção
package br.com.cliente; import br.com.server.Server; import java.io.PipedOutputStream; /** * Thread para Correcao * * @author Filipe */ public class ClientCorrecao extends AbstractClient { public ClientCorrecao(PipedOutputStream pOut1, PipedOutputStream pOut2, PipedOutputStream pOut3) { super(pOut1, pOut2, pOut3); } @Override protected void write() { this.value = Server.CORRECAO; } }
Cliente Saque
package br.com.cliente; import br.com.server.Server; import java.io.PipedOutputStream; /** * Thread para saque * * @author Filipe */ public class ClientSaque extends AbstractClient { public ClientSaque(PipedOutputStream pOut1, PipedOutputStream pOut2, PipedOutputStream pOut3) { super(pOut1, pOut2, pOut3); } @Override protected void write() { this.value = Server.SAQUE; } }
Receptor abstrato
package br.com.receptor; import br.com.server.Server; import java.io.DataInputStream; import java.io.IOException; import java.io.PipedInputStream; import java.util.logging.Level; import java.util.logging.Logger; /** * Essa classe sera responsavel por enviar a informaçao ao servidor * * @author Filipe */ public abstract class AbstractReceptor extends Thread { //Leitor protected DataInputStream dIn; protected final Server server; public AbstractReceptor(PipedInputStream pis, Server server) { this.dIn = new DataInputStream(pis); this.server = server; } //Saque deposito ou correcao public abstract void action(float value); @Override public void run() { for (int i = 0; i < 9; i++) { try { //System.out.println("Aguardando ..."); //blocante float valor = dIn.readFloat(); //acao do receptor action(valor); } catch (IOException ex) { //if (!ex.getMessage().equals("Pipe closed")) { Logger.getLogger(AbstractReceptor.class.getName()).log(Level.SEVERE, null, ex); } } } }
Receptor Deposito
package br.com.receptor; import java.io.PipedInputStream; import br.com.server.Server; /** * Repassa o deposito pro valor pro servidor * */ public class ReceptorDeposito extends AbstractReceptor { public ReceptorDeposito(PipedInputStream pis, Server server) { super(pis, server); } @Override public void action(float value) { System.out.println("Transferindo deposito: " + value); if (server != null) { this.server.depositar(); } } }
Receptor Saque
package br.com.receptor; import java.io.PipedInputStream; import br.com.server.Server; public class ReceptorSaque extends AbstractReceptor { public ReceptorSaque(PipedInputStream pis, Server server) { super(pis, server); } @Override public void action(float value) { System.out.println("Sacando: " + value); if (server != null) { this.server.sacar(); } } }
Receptor Correção
package br.com.receptor; import java.io.PipedInputStream; import br.com.server.Server; public class ReceptorCorrecao extends AbstractReceptor { public ReceptorCorrecao(PipedInputStream pis, Server server) { super(pis, server); } @Override public void action(float value) { if (server != null) { System.out.println("Aplicando correção: " + value); this.server.correcao(); } } }
Servidor
package br.com.server; import br.com.receptor.ReceptorCorrecao; import br.com.receptor.ReceptorDeposito; import br.com.receptor.ReceptorSaque; import java.io.PipedInputStream; public class Server extends Thread { /** * Identificado para o servidor */ private static int ID = 1; /** * Salvo sera acessado simultaneamente entao preciso ler da memoria * principal */ private final int id; private volatile float saldo; private ReceptorDeposito rdeposito; private ReceptorSaque rsaque; private ReceptorCorrecao rcorrecao; public static final float SAQUE = 3; public static final float DEPOSITO = 10; public static final float CORRECAO = 0.1f; public Server() { this.saldo = 10; this.id = ID; ID++; } public Server(float saldo, PipedInputStream p1, PipedInputStream p2, PipedInputStream p3) { this.saldo = saldo; this.rdeposito = new ReceptorDeposito(p1, this); this.rsaque = new ReceptorSaque(p2, this); this.rcorrecao = new ReceptorCorrecao(p3, this); this.id = ID; ID++; } public Server(PipedInputStream p1, PipedInputStream p2, PipedInputStream p3) { this(100, p1, p2, p3); } @Override public void run() { this.rdeposito.start(); this.rsaque.start(); this.rcorrecao.start(); } public synchronized void depositar() { System.out.println("Depositado: " + DEPOSITO + " no Servidor: " + id); this.saldo += DEPOSITO; } public synchronized void sacar() { System.out.println("Sacado: " + SAQUE + " no Servidor: " + id); this.saldo -= SAQUE; } public synchronized void correcao() { System.out.println("Correção aplicada: " + CORRECAO + " no Servidor: " + id); this.saldo = saldo + (saldo * CORRECAO); } public float getSaldo() { return saldo; } public void setSaldo(float saldo) { this.saldo = saldo; } public boolean isAllAlive() { return (rdeposito.isAlive() || rsaque.isAlive() || rcorrecao.isAlive()); } @Override public String toString() { return "Server: " + id + " => Saldo: " + saldo; } }
Controller
package br.com.server; import br.com.cliente.ClientCorrecao; import br.com.cliente.ClientDeposito; import br.com.cliente.ClientSaque; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * * Classe que controla sincronismo com todos so servidores * * @author Filipe */ public class Controller { private final List<Server> servers; private boolean open; public Controller() { this.servers = new ArrayList<>(); } public void runServer() { init(); for (Server s : servers) { while (s.isAllAlive()) { //espera } } System.out.println("SALDO FINAL"); for (Server s : servers) { System.out.println(s); } } /** * Cria os piped out e in */ private void init() { try { //criando mensageiro para cliente enviar ao receptor //criando canal de comunicao para receptor //Server 1 PipedOutputStream s1out1 = new PipedOutputStream(); PipedInputStream s1in1 = new PipedInputStream(s1out1); PipedOutputStream s1out2 = new PipedOutputStream(); PipedInputStream s1in2 = new PipedInputStream(s1out2); PipedOutputStream s1out3 = new PipedOutputStream(); PipedInputStream s1in3 = new PipedInputStream(s1out3); //Server 2 PipedOutputStream s2out1 = new PipedOutputStream(); PipedInputStream s2in1 = new PipedInputStream(s2out1); PipedOutputStream s2out2 = new PipedOutputStream(); PipedInputStream s2in2 = new PipedInputStream(s2out2); PipedOutputStream s2out3 = new PipedOutputStream(); PipedInputStream s2in3 = new PipedInputStream(s2out3); //Server 3 PipedOutputStream s3out1 = new PipedOutputStream(); PipedInputStream s3in1 = new PipedInputStream(s3out1); PipedOutputStream s3out2 = new PipedOutputStream(); PipedInputStream s3in2 = new PipedInputStream(s3out2); PipedOutputStream s3out3 = new PipedOutputStream(); PipedInputStream s3in3 = new PipedInputStream(s3out3); //cria o servidor com 3 receptores //inicializa os receptores Server server1 = new Server(100, s1in1, s1in2, s1in3); this.servers.add(server1); Server server2 = new Server(100, s2in1, s2in2, s2in3); this.servers.add(server2); Server server3 = new Server(100, s3in1, s3in2, s3in3); this.servers.add(server3); //clientes new ClientDeposito(s1out1, s1out2, s1out3).start(); server1.start(); new ClientSaque(s2out1, s2out2, s2out3).start(); server2.start(); new ClientCorrecao(s3out1, s3out2, s3out3).start(); server3.start(); } catch (IOException ex) { Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex); } } public boolean isOpen() { return open; } public void setOpen(boolean status) { this.open = status; } }
Mensagens: 1
Participantes: 1