Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package algoritmoricartagrawala;
- import java.io.IOException;
- import static java.lang.Math.random;
- import static java.lang.StrictMath.random;
- import java.net.DatagramPacket;
- import java.net.InetAddress;
- import java.net.MulticastSocket;
- import java.net.SocketTimeoutException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.Scanner;
- /**
- *
- * @author giovanne.gaspareto
- */
- public class AlgoritmoRicartAgrawala {
- static InetAddress grupo;
- static MulticastSocket s;
- static DatagramPacket msg;
- static DatagramPacket recv;
- private static Scanner keyboard;
- static boolean executarProcesso = true;
- static boolean aguardaPermissaoRegiaoCritica = false;
- static boolean regiaoCritica = false;
- static final String GROUP_IP = "224.0.0.1";
- static final int MULTICAST_PORT = 2000;
- static int IDProcesso = 0;
- static String mensagem = "";
- static int numeroProcessosGrupo = 0;
- static int tempoRandom = 0;
- static int idProcessoNaRegiaoCritica = 0;
- static int idRecebido = 0;
- static int proximo = 0;
- static final String OK_STRING = "ok";
- static final String DESCONECTAR_STRING = "q";
- static final String DIVISOR_STRING = ";";
- static final String GRUPO_COMPLETO_STRING = "gc";
- static final String EXISTE_PROCESSO_REGIAO_CRITICA = "regiao critica";
- static final String REQUISICAO_REG_CRITICA_STRING = "rc";
- static final String SAINDO_REGIAO_CRITICA_STRING = "sc";
- static final String ENTROU_REGIAO_CRITICA_STRING = "ec";
- static final int NOVO_MEMBRO = 1;
- static final int GRUPO_COMPLETO = 2;
- static final int REQUISICAO_REG_CRITICA = 3;
- static final int SAINDO_REGIAO_CRITICA = 4;
- static final int ENTROU_REGIAO_CRITICA = 5;
- static List<Integer> listaEsperaRegiaoCritica = new ArrayList<Integer>(); //lista com IDs dos processos aguardando pela regiao critica
- public static String receiveMessageGroup(){
- byte[] buf=new byte[1000];
- recv=new DatagramPacket(buf, buf.length);
- try {
- s.setSoTimeout(10);
- s.setLoopbackMode(false);
- // System.out.println("timeout no recevei sem nada: " + s.getSoTimeout());
- s.receive(recv);
- byte[] dest=new byte[recv.getLength()];
- System.arraycopy(recv.getData(), 0, dest, 0, dest.length);
- String mensagemRecebida = new String(recv.getData(),recv.getOffset(),recv.getLength());
- // System.err.println("Mensagen recebida: "+ mensagemRecebida);
- return mensagemRecebida;
- } catch (SocketTimeoutException ex) {
- // Logger.getLogger(ProcessoSender.class.getName()).log(Level.SEVERE, null, ex);
- return "x;0;0";
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return "x;0;0";
- }
- }
- public static void sendMessageGroup(String msgStr) {
- msg=new DatagramPacket(msgStr.getBytes(), msgStr.length(),grupo, 2000);
- // System.out.println("Enviando mensagem para o grupo ...");
- try {
- s.send(msg);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- //Funcao de configuracao
- public static void setUp() {
- try {
- System.setProperty("java.net.preferIPv4Stack", "true"); // somente pra mac no wifi
- grupo=InetAddress.getByName(GROUP_IP);
- s=new MulticastSocket(MULTICAST_PORT);
- System.err.println("Entrando no grupo ...");
- s.joinGroup(grupo);
- System.err.println("Ok.");
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static int geraRandomEntre(int min, int max){
- Random rn = new Random();
- return rn.nextInt(max-min+1)+min;
- }
- /**
- * @param args the command line arguments
- */
- public static int trataMensagem(String mensagemRecebida, DatagramPacket PacketLider){
- String[] partes = mensagemRecebida.split(DIVISOR_STRING);
- String operacao = partes[0];
- String mensagem = partes[1];
- idRecebido = Integer.parseInt(mensagem);
- if(operacao.equals(OK_STRING)){
- return NOVO_MEMBRO;
- }
- else if(operacao.equals(GRUPO_COMPLETO_STRING)){
- return GRUPO_COMPLETO;
- }else if(operacao.equals(REQUISICAO_REG_CRITICA_STRING)){
- return REQUISICAO_REG_CRITICA;
- }else if(operacao.equals(SAINDO_REGIAO_CRITICA_STRING)){
- idProcessoNaRegiaoCritica = 0;
- return SAINDO_REGIAO_CRITICA;
- }else if(operacao.equals(ENTROU_REGIAO_CRITICA_STRING)){
- idProcessoNaRegiaoCritica = Integer.parseInt(mensagem);
- return ENTROU_REGIAO_CRITICA;
- }
- return -1;
- }
- public static void defineIDProcesso(){
- keyboard = new Scanner(System.in);
- System.out.println("Informe o ID deste processo: ");
- IDProcesso = keyboard.nextInt();
- }
- public static void lerGrupoTrataMensagem(){
- 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
- //ler mensagens ate receber ok que a regiao critica esta livre
- case REQUISICAO_REG_CRITICA:
- //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
- listaEsperaRegiaoCritica.add(idRecebido);
- proximo = listaEsperaRegiaoCritica.get(0);
- if(proximo == IDProcesso && idProcessoNaRegiaoCritica == 0){ //é o primeiro da fila e nao ha nenhum processo na regiao critica
- aguardaPermissaoRegiaoCritica = false;
- regiaoCritica = true;
- }
- break;
- case SAINDO_REGIAO_CRITICA:
- //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
- proximo = listaEsperaRegiaoCritica.get(0);
- System.out.println("[Processo "+ IDProcesso + "] Proximo da lista: " + proximo);
- if(proximo == IDProcesso){
- aguardaPermissaoRegiaoCritica = false; //este processo é o proximo da fila, sai do loop de espera espera
- //sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando
- regiaoCritica = true;
- }
- break;
- case ENTROU_REGIAO_CRITICA:
- //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
- // remove ID do processo que entrou da lista de espera
- listaEsperaRegiaoCritica.remove(0);
- break;
- }
- }
- public static void lerGrupoRegiaoNaoCritica(){
- 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
- //ler mensagens ate receber ok que a regiao critica esta livre
- case REQUISICAO_REG_CRITICA:
- //Recebeu uma requisicao de regiao critica, todos atualizam a lista de espera
- listaEsperaRegiaoCritica.add(idRecebido);
- break;
- case ENTROU_REGIAO_CRITICA:
- //se idProcesso = idProcessoNaRegiaoCritica, significa que pode entrar. aguardaPermissaoRegiaoCritica = false, regiaoCritica = true
- // remove ID do processo que entrou da lista de espera
- // 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
- listaEsperaRegiaoCritica.remove(0);
- break;
- }
- }
- public static void aguardaMembrosDoGrupo(){
- while(numeroProcessosGrupo<3){
- switch(trataMensagem(receiveMessageGroup(),recv)){
- case NOVO_MEMBRO:
- numeroProcessosGrupo ++;
- System.out.println("Novo processo Conectado ao Grupo!");
- break;
- case GRUPO_COMPLETO:
- numeroProcessosGrupo = 3;
- break;
- default:
- // System.out.println("Case Default da espera grupo");
- break;
- }
- }
- sendMessageGroup(GRUPO_COMPLETO_STRING+DIVISOR_STRING+IDProcesso);
- }
- public static void main(String[] args) {
- setUp();
- defineIDProcesso();
- sendMessageGroup(OK_STRING+DIVISOR_STRING+IDProcesso);
- aguardaMembrosDoGrupo();
- System.out.println("Grupo completo! Iniciar execucao.");
- tempoRandom = geraRandomEntre(2,16);
- //tempoRandom = 3;
- TimerProcessos timerAleatorio = new TimerProcessos(tempoRandom);
- System.out.println("[Processo " + IDProcesso + "] Entrando na regiao nao critica por " + tempoRandom + "s");
- while(executarProcesso){
- if(timerAleatorio.shouldCreate){
- //passou o tempo, entra ou sai da regiao critica
- if(aguardaPermissaoRegiaoCritica){//se estava na critica, agora nao esta mais
- aguardaPermissaoRegiaoCritica = false;
- tempoRandom = geraRandomEntre(2,16);
- }else{//se estava fora, agora fica na critica
- aguardaPermissaoRegiaoCritica = true;
- }
- }
- if(aguardaPermissaoRegiaoCritica){
- //fazer coisas da regiao critica
- System.out.println("[Processo " + IDProcesso + "] Aguardando entrada na regiao critica!");
- //Notifica a todos que deseja estar na regiao critica
- sendMessageGroup(REQUISICAO_REG_CRITICA_STRING + DIVISOR_STRING + IDProcesso);
- while(aguardaPermissaoRegiaoCritica){
- lerGrupoTrataMensagem();
- }
- sendMessageGroup(ENTROU_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //avisa outros processos que esta entrando na regiao critica
- //Iniciar timer da regiao critica
- timerAleatorio.cancelTimer();
- timerAleatorio = new TimerProcessos(tempoRandom);
- System.err.println("[Processo " + IDProcesso + "] Entrando na regiao critica! Tempo dentro da regiao: " + tempoRandom + "s");
- regiaoCritica = true;
- while(regiaoCritica){
- //verifica timer, muda regiaoCritica para false apos fim do timer
- if(timerAleatorio.shouldCreate){
- regiaoCritica = false;
- //Inicia timer da regiao nao critica
- timerAleatorio.cancelTimer();
- tempoRandom = geraRandomEntre(2,16);
- timerAleatorio = new TimerProcessos(tempoRandom);
- }
- lerGrupoTrataMensagem();
- //Ainda ler grupo, para atualizar lista de espera
- }
- System.err.println("[Processo " + IDProcesso + "]Fim da regiao critica!");
- sendMessageGroup(SAINDO_REGIAO_CRITICA_STRING + DIVISOR_STRING + IDProcesso); //notifica que saiu da regiao critica
- System.out.println("[Processo " + IDProcesso + "] Executando na regiao nao critica por " + tempoRandom + "s");
- }else{
- //fazer coisas da regiao nao critica
- //Ler grupo para atualizar controle de quem esta na regiao critica e atualizar a lista de espera
- lerGrupoRegiaoNaoCritica();
- }
- }
- System.exit(0);
- }
- }
Advertisement