Bressam

AlgoritmoRicartAgrawala

Jun 28th, 2018
321
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.02 KB | None | 0 0
  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6. package algoritmoricartagrawala;
  7.  
  8. import java.io.IOException;
  9. import static java.lang.Math.random;
  10. import static java.lang.StrictMath.random;
  11. import java.net.DatagramPacket;
  12. import java.net.InetAddress;
  13. import java.net.MulticastSocket;
  14. import java.net.SocketTimeoutException;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.Random;
  18. import java.util.Scanner;
  19.  
  20. /**
  21.  *
  22.  * @author giovanne.gaspareto
  23.  */
  24. public class AlgoritmoRicartAgrawala {
  25.     static InetAddress              grupo;
  26.     static MulticastSocket          s;
  27.     static DatagramPacket           msg;
  28.     static DatagramPacket           recv;
  29.     private static Scanner          keyboard;
  30.    
  31.    
  32.     static boolean                  executarProcesso = true;
  33.     static boolean                  aguardaPermissaoRegiaoCritica = false;
  34.     static boolean                  regiaoCritica = false;
  35.    
  36.     static final String         GROUP_IP = "224.0.0.1";
  37.     static final int            MULTICAST_PORT = 2000;
  38.     static int                  IDProcesso = 0;
  39.     static String               mensagem = "";
  40.     static int                  numeroProcessosGrupo = 0;
  41.     static int                  tempoRandom = 0;
  42.     static int                  idProcessoNaRegiaoCritica = 0;
  43.     static int                  idRecebido = 0;
  44.     static int                  proximo =   0;
  45.    
  46.    
  47.    
  48.     static final String         OK_STRING = "ok";
  49.     static final String         DESCONECTAR_STRING = "q";
  50.     static final String         DIVISOR_STRING = ";";
  51.     static final String         GRUPO_COMPLETO_STRING = "gc";
  52.     static final String         EXISTE_PROCESSO_REGIAO_CRITICA = "regiao critica";
  53.     static final String         REQUISICAO_REG_CRITICA_STRING  =   "rc";
  54.     static final String         SAINDO_REGIAO_CRITICA_STRING  = "sc";
  55.     static final String         ENTROU_REGIAO_CRITICA_STRING = "ec";
  56.    
  57.     static final int            NOVO_MEMBRO = 1;
  58.     static final int            GRUPO_COMPLETO = 2;
  59.     static final int            REQUISICAO_REG_CRITICA = 3;
  60.     static final int            SAINDO_REGIAO_CRITICA = 4;
  61.     static final int            ENTROU_REGIAO_CRITICA = 5;
  62.    
  63.    
  64.     static List<Integer> listaEsperaRegiaoCritica = new ArrayList<Integer>();  //lista com IDs dos processos aguardando pela regiao critica
  65.    
  66.    
  67.     public static String receiveMessageGroup(){
  68.         byte[] buf=new byte[1000];
  69.         recv=new DatagramPacket(buf, buf.length);
  70.         try {
  71.             s.setSoTimeout(10);
  72.             s.setLoopbackMode(false);
  73.            // System.out.println("timeout no recevei sem nada: " + s.getSoTimeout());
  74.             s.receive(recv);
  75.             byte[] dest=new byte[recv.getLength()];
  76.             System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
  77.             String mensagemRecebida = new String(recv.getData(),recv.getOffset(),recv.getLength());
  78.          //   System.err.println("Mensagen recebida: "+ mensagemRecebida);
  79.             return mensagemRecebida;
  80.         } catch (SocketTimeoutException ex) {
  81.           // Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
  82.             return "x;0;0";
  83.     } catch (IOException e) {
  84.             // TODO Auto-generated catch block
  85.             e.printStackTrace();
  86.             return "x;0;0";
  87.         }
  88.     }
  89.     public static void sendMessageGroup(String msgStr) {
  90.         msg=new DatagramPacket(msgStr.getBytes(), msgStr.length(),grupo, 2000);
  91.        // System.out.println("Enviando mensagem para o grupo ...");
  92.         try {
  93.             s.send(msg);
  94.         } catch (IOException e) {
  95.             // TODO Auto-generated catch block
  96.             e.printStackTrace();
  97.         }
  98.     }
  99.    
  100.     //Funcao de configuracao
  101.     public static void setUp() {
  102.         try {
  103.             System.setProperty("java.net.preferIPv4Stack", "true"); // somente pra mac no wifi
  104.             grupo=InetAddress.getByName(GROUP_IP);
  105.             s=new MulticastSocket(MULTICAST_PORT);
  106.             System.err.println("Entrando no grupo ...");
  107.             s.joinGroup(grupo);
  108.             System.err.println("Ok.");
  109.         } catch (IOException e) {
  110.             // TODO Auto-generated catch block
  111.             e.printStackTrace();
  112.         }
  113.        
  114.     }
  115.    
  116.     public static int geraRandomEntre(int min, int max){
  117.         Random rn = new Random();
  118.         return rn.nextInt(max-min+1)+min;
  119.     }
  120.     /**
  121.      * @param args the command line arguments
  122.      */
  123.    
  124.     public static int trataMensagem(String mensagemRecebida, DatagramPacket PacketLider){
  125.         String[] partes = mensagemRecebida.split(DIVISOR_STRING);
  126.         String operacao = partes[0];
  127.         String mensagem = partes[1];
  128.         idRecebido = Integer.parseInt(mensagem);
  129.        
  130.         if(operacao.equals(OK_STRING)){
  131.             return  NOVO_MEMBRO;
  132.         }
  133.         else if(operacao.equals(GRUPO_COMPLETO_STRING)){
  134.             return GRUPO_COMPLETO;
  135.         }else if(operacao.equals(REQUISICAO_REG_CRITICA_STRING)){
  136.             return REQUISICAO_REG_CRITICA;
  137.         }else if(operacao.equals(SAINDO_REGIAO_CRITICA_STRING)){
  138.             idProcessoNaRegiaoCritica = 0;
  139.             return SAINDO_REGIAO_CRITICA;
  140.         }else if(operacao.equals(ENTROU_REGIAO_CRITICA_STRING)){
  141.             idProcessoNaRegiaoCritica = Integer.parseInt(mensagem);
  142.             return ENTROU_REGIAO_CRITICA;
  143.         }
  144.         return -1;
  145.     }
  146.    
  147.     public static void defineIDProcesso(){
  148.         keyboard = new Scanner(System.in);
  149.         System.out.println("Informe o ID deste processo: ");
  150.         IDProcesso = keyboard.nextInt();
  151.     }
  152.    
  153.     public static void lerGrupoTrataMensagem(){
  154.         switch(trataMensagem(receiveMessageGroup(),recv)){//só cria timer apos estar de fato atuando na regiao critica, so acontecera quando receber um ok que o processo anterior liberou ela
  155.             //ler mensagens ate receber ok que a regiao critica esta livre
  156.             case REQUISICAO_REG_CRITICA:
  157.                 //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
  158.                 listaEsperaRegiaoCritica.add(idRecebido);
  159.                 proximo = listaEsperaRegiaoCritica.get(0);
  160.                 if(proximo == IDProcesso && idProcessoNaRegiaoCritica == 0){ //é o primeiro da fila e nao ha nenhum processo na regiao critica
  161.                    
  162.                     aguardaPermissaoRegiaoCritica = false;
  163.                     regiaoCritica = true;
  164.                 }
  165.                 break;
  166.  
  167.             case SAINDO_REGIAO_CRITICA:
  168.                 //verificar se seu proprio ID é o proximo a entrar na regiao critica, se for, envia que entrou e inicia timer, senao salva o id de quem entrou
  169.                 proximo = listaEsperaRegiaoCritica.get(0);
  170.                 System.out.println("[Processo "+ IDProcesso + "] Proximo da lista: " + proximo);
  171.                 if(proximo == IDProcesso){
  172.                      aguardaPermissaoRegiaoCritica = false; //este processo é o proximo da fila, sai do loop de espera espera
  173.                     //sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando
  174.                     regiaoCritica = true;
  175.                 }
  176.                 break;
  177.  
  178.             case ENTROU_REGIAO_CRITICA:
  179.                 //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
  180.                 // remove ID do processo que entrou da lista de espera
  181.                 listaEsperaRegiaoCritica.remove(0);
  182.                 break;  
  183.         }
  184.     }
  185.    
  186.    public static void lerGrupoRegiaoNaoCritica(){
  187.                        switch(trataMensagem(receiveMessageGroup(),recv)){//só cria timer apos estar de fato atuando na regiao critica, so acontecera quando receber um ok que o processo anterior liberou ela
  188.                     //ler mensagens ate receber ok que a regiao critica esta livre
  189.                     case REQUISICAO_REG_CRITICA:
  190.                         //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
  191.                         listaEsperaRegiaoCritica.add(idRecebido);
  192.                         break;
  193.  
  194.                     case ENTROU_REGIAO_CRITICA:
  195.                         //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
  196.                         // remove ID do processo que entrou da lista de espera
  197.                        // if(IDProcesso != idRecebido){ //somente se for outro processo lendo que alguem entrou. Se for o proprio processo, ele ja se removeu da lista ao avaliar que era o proximo
  198.                            listaEsperaRegiaoCritica.remove(0);
  199.  
  200.                         break;  
  201.                 }
  202.     }
  203.    
  204.    public static void aguardaMembrosDoGrupo(){
  205.     while(numeroProcessosGrupo<3){
  206.             switch(trataMensagem(receiveMessageGroup(),recv)){
  207.                 case NOVO_MEMBRO:
  208.                     numeroProcessosGrupo ++;
  209.                     System.out.println("Novo processo Conectado ao Grupo!");
  210.                     break;
  211.                
  212.                 case GRUPO_COMPLETO:
  213.                     numeroProcessosGrupo = 3;
  214.                     break;
  215.                 default:
  216.                   //  System.out.println("Case Default da espera grupo");
  217.                     break;
  218.             }
  219.         }
  220.         sendMessageGroup(GRUPO_COMPLETO_STRING+DIVISOR_STRING+IDProcesso);
  221.    }
  222.    
  223.    public static void main(String[] args) {
  224.        
  225.         setUp();
  226.         defineIDProcesso();
  227.         sendMessageGroup(OK_STRING+DIVISOR_STRING+IDProcesso);
  228.        
  229.         aguardaMembrosDoGrupo();
  230.        
  231.         System.out.println("Grupo completo! Iniciar execucao.");
  232.        
  233.         tempoRandom = geraRandomEntre(2,16);
  234.         //tempoRandom = 3;
  235.         TimerProcessos timerAleatorio = new TimerProcessos(tempoRandom);
  236.         System.out.println("[Processo " + IDProcesso + "] Entrando na regiao nao critica por " + tempoRandom + "s");
  237.         while(executarProcesso){
  238.            
  239.             if(timerAleatorio.shouldCreate){
  240.                
  241.                 //passou o tempo, entra ou sai da regiao critica
  242.                 if(aguardaPermissaoRegiaoCritica){//se estava na critica, agora nao esta mais
  243.                     aguardaPermissaoRegiaoCritica = false;
  244.                     tempoRandom = geraRandomEntre(2,16);
  245.                 }else{//se estava fora, agora fica na critica
  246.                     aguardaPermissaoRegiaoCritica = true;
  247.                 }  
  248.             }
  249.            
  250.             if(aguardaPermissaoRegiaoCritica){
  251.                 //fazer coisas da regiao critica
  252.                 System.out.println("[Processo " + IDProcesso + "] Aguardando entrada na regiao critica!");
  253.                
  254.                 //Notifica a todos que deseja estar na regiao critica
  255.                 sendMessageGroup(REQUISICAO_REG_CRITICA_STRING + DIVISOR_STRING + IDProcesso);
  256.  
  257.                 while(aguardaPermissaoRegiaoCritica){
  258.                     lerGrupoTrataMensagem();
  259.                 }
  260.                 sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando na regiao critica
  261.                 //Iniciar timer da regiao critica
  262.                 timerAleatorio.cancelTimer();
  263.                 timerAleatorio = new TimerProcessos(tempoRandom);
  264.                 System.err.println("[Processo " + IDProcesso + "] Entrando na regiao critica! Tempo dentro da regiao: " + tempoRandom + "s");
  265.                 regiaoCritica = true;
  266.                 while(regiaoCritica){
  267.                     //verifica timer, muda regiaoCritica para false apos fim do timer
  268.                     if(timerAleatorio.shouldCreate){
  269.                         regiaoCritica = false;
  270.                        
  271.                         //Inicia timer da regiao nao critica          
  272.                         timerAleatorio.cancelTimer();
  273.                         tempoRandom = geraRandomEntre(2,16);
  274.                         timerAleatorio = new TimerProcessos(tempoRandom);
  275.                     }
  276.                     lerGrupoTrataMensagem();
  277.                     //Ainda ler grupo, para atualizar lista de espera
  278.                 }
  279.                 System.err.println("[Processo " + IDProcesso + "]Fim da regiao critica!");
  280.                 sendMessageGroup(SAINDO_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //notifica que saiu da regiao critica
  281.                 System.out.println("[Processo " + IDProcesso + "] Executando na regiao nao critica por " + tempoRandom + "s");
  282.             }else{
  283.                 //fazer coisas da regiao nao critica
  284.                 //Ler grupo para atualizar controle de quem esta na regiao critica e atualizar a lista de espera
  285.                 lerGrupoRegiaoNaoCritica();
  286.             }
  287.            
  288.         }
  289.         System.exit(0);
  290.     }
  291.    
  292. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment