package jantardosfilosofos; import javax.swing.JFrame; /** * Pós-Java PGN0060 * * @Monteiro */ public class JantarDosFilosofos extends JFrame { public JantarDosFilosofos() { // Janela add(new Grade()); // Titulo setTitle("Jantar dos Filósofos"); // Operação ao fechar a janela setDefaultCloseOperation(EXIT_ON_CLOSE); // Tamanho do frame setSize(500, 500); // Local setLocationRelativeTo(null); // Visibilidade setVisible(true); // Bloqueia o redimensionamento setResizable(false); } public static void main(String[] args) { new JantarDosFilosofos(); } } package jantardosfilosofos; /** * Pós-Java PGN0060 * @Monteiro 19/03/2016 */ public class Filosofo extends Thread { // Cria um código privado para o filósofo private int ID; // Cria padrões de comportamento do filósofo final int PENSANDO = 0; final int FAMINTO = 1; final int COMENDO = 2; // Método construtor que recebe um nome para a classe e um código de // identificação do filósofo public Filosofo (String nome, int ID) { super(nome); this.ID = ID; } // Método para definir que o filósofo está com fome public void ComFome () { // Seta o estado deste filósofo na classe Grade para FAMINTO Grade.estado[this.ID] = 1; // Exibe uma mensagem de controle na tela System.out.println("O Filósofo " + getName() + " está FAMINTO!"); } // Método para definir que o filósofo está comendo public void Come () { // Seta o estado deste filósofo na classe Grade para COMENDO Grade.estado[this.ID] = 2; // Exibe uma mensagem de controle na tela System.out.println("O Filósofo " + getName() + " está COMENDO!"); // Será criado um controle para o filósofo permanecer comendo // durante certo período de tempo try { // Fica parado neste estado por 1000 milisegundos Thread.sleep(1000L); } catch (InterruptedException ex) { // Exibe uma mensagem de controle de erro System.out.println("ERROR>" + ex.getMessage()); } } // Método para definir que o filósofo está pensando public void Pensa () { // Seta o estado deste filósofo na classe Grade para PENSANDO Grade.estado[this.ID] = 0; // Exibe uma mensagem de controle na tela System.out.println("O Filósofo " + getName() + " está PENSANDO!"); // Será criado um controle para o filósofo permanecer pensando // durante certo período de tempo try { // Fica parado neste estado por 1000 milisegundos Thread.sleep(1000L); } catch (InterruptedException ex) { // Exibe uma mensagem de controle de erro System.out.println("ERROR>" + ex.getMessage()); } } // Método para o filósofo soltar um garfo que ele pegou public void LargarGarfo () { // Decrementa o semáforo mutex principal da classe, isso permite // informar que o atual método está operando na mesa dos filósofos Grade.mutex.decrementar(); // Coloca o filósofo para pensar determinado tempo Pensa(); // Após o filósofo pensar, ele vai informar para os seus vizinhos // que podem tentar pegar os garfos que já estão disponíveis Grade.filosofo[VizinhoEsquerda()].TentarObterGarfos(); Grade.filosofo[VizinhoDireita()].TentarObterGarfos(); // Após operar, volta o semáforo mutex para o estado normal // indicando que já realizou todos procedimentos na mesa Grade.mutex.incrementar(); } // Método para o filósofo pegar um garfo na mesa public void PegarGarfo () { // Decrementa o semáforo mutex principal da classe, isso permite // informar que o atual método está operando na mesa dos filósofos Grade.mutex.decrementar(); // Deixa o filósofo faminto por determinado tempo ComFome(); // Após o filósofo o período de fome, ele vai verificar com seus // vizinhos se ele pode pegar os garfos TentarObterGarfos(); // Após operar, volta o semáforo mutex para o estado normal // indicando que já realizou todos procedimentos na mesa Grade.mutex.incrementar(); // Decrementa seu semáforo Grade.semaforos[this.ID].decrementar(); } // Método para verificar se o filósofo pode pegar um garfo disposto na mesa public void TentarObterGarfos() { // Verifica se este filósofo está com fome, e se o vizinho da esquerda // e da direita não estão comendo if (Grade.estado[this.ID] == 1 && Grade.estado[VizinhoEsquerda()] != 2 && Grade.estado[VizinhoDireita()] != 2) { // Então este filósofo pode comer Come(); // E incrementa o seu semáforo Grade.semaforos[this.ID].incrementar(); } } // Método de execução da classe, onde o ambiente do filósofo será rodado @Override public void run () { try { // Coloca o filósofo para pensar Pensa(); // Então realiza uma vida infinita para o filósofo onde inicialmente // ele executa os procedimentos de pergar os garfos da mesa, posteriormente // ele descansa um pouco, e por fim, ele largar os garfos que ele pegou do { PegarGarfo(); Thread.sleep(1000L); LargarGarfo(); } while (true); } catch (InterruptedException ex) { // Exibe uma mensagem de controle de erro System.out.println("ERROR>" + ex.getMessage()); // E da um retorno de cancelamento return; } } // Método para obter o filósofo vizinho da direita public int VizinhoDireita () { // Rationa o valor em 5 posições, ou seja, se o ID deste filósofo acrescentado // de um for maior que quatro, passa a ser zero return (this.ID + 1) % 5; } // Método para obter o filósofo vizinho da esquerda public int VizinhoEsquerda () { if (this.ID == 0) { // Retorna a ultima posição return 4; } else { // Rationa o valor em 5 posições, ou seja, se o ID deste filósofo decrescido // de um for menor que zero, passa a ser quatro return (this.ID - 1) % 5; } } } package jantardosfilosofos; /** * * @author aluno */ public class Semaforo { // Criação de um contador protegido para esta classe protected int contador; // Método construtor da classe que não recebe nenhum valor public Semaforo () { this.contador = 0; } // Método construtor da classe que recebe um valor para setar no // contador public Semaforo (int valor) { this.contador = valor; } // Método de sincronização da classe onde será decrescido o contador public synchronized void decrementar () { // Enquanto o contador for igual a 0, ele aguarda e trata a exceção while (this.contador == 0) { try { // Espera uma nova solicitação wait(); } catch (InterruptedException ex) { // Exibe uma mensagem de controle de erro System.out.println("ERROR>" + ex.getMessage()); } } // Caso tenha saído do while acima, então decrementa o // contador da classe this.contador--; } // Método de sincronização da classe onde será incrementado o contador public synchronized void incrementar () { // Incrementa o contador da classe this.contador++; // Notifica que a solicitação já foi executada notify(); } } package jantardosfilosofos; import java.awt.Color; import java.awt.Graphics; import java.awt.Toolkit; import javax.swing.JPanel; /** * * @author aluno */ public class Grade extends JPanel implements Runnable{ // Cria padrões de comportamento dos filósofos final int PENSANDO = 0; final int FAMINTO = 1; final int COMENDO = 2; // Mensagem para cada um dos estados String mensagem = ""; // Thread principal da aplicação Thread animador; // Criação dos semáforos da aplicação // O semáforo mutex que recebe o valor incial 1 para o contador // e é o semáforo principal da nossa aplicação public static Semaforo mutex = new Semaforo(1); // O vetor semáforos são normais e existe um semáforo para cada filósofo // que será criado, esses semafóros não recebem valores de inicialização // portanto iniciando o contador em 0 public static Semaforo semaforos[] = new Semaforo[5]; // Define um vetor para o estado de cada um dos filósofos presentes // na aplicação public static int estado[] = new int[5]; // Cria 5 filósofos em um vetor para a aplicação static Filosofo filosofo[] = new Filosofo[5]; // Método construtor da Grade da aplicação public Grade () { // Define o foco para este JPanel setFocusable(true); // Define um tamanho para a tela setSize(400, 400); // Seta a cor do fundo setBackground(Color.white); init(); } // Método para inicializar tudo o que é preciso dentro da classe public void init () { // Inicializa todos estados para zero for (int i = 0; i < estado.length; i++) { estado[i] = 0; } // Verifica se o Thread de animação é vazio if(animador == null) { // Então cria um novo Thread animador = new Thread(this); // Inicia sua execução animador.start(); } // Define a prioridade principal para este atual Thread Thread.currentThread().setPriority(1); // Inicializa todos filósofos filosofo[0] = new Filosofo("Platao", 0); filosofo[1] = new Filosofo("Socrates", 1); filosofo[2] = new Filosofo("Aristoteles", 2); filosofo[3] = new Filosofo("Tales", 3); filosofo[4] = new Filosofo("Sofocles", 4); // Inicializa todos semáforos semaforos[0] = new Semaforo(0); semaforos[1] = new Semaforo(0); semaforos[2] = new Semaforo(0); semaforos[3] = new Semaforo(0); semaforos[4] = new Semaforo(0); // Inicia a execução de todos filósofos filosofo[0].start(); filosofo[1].start(); filosofo[2].start(); filosofo[3].start(); filosofo[4].start(); } // Método para desenhar os objetos na tela da aplicação @Override public void paint(Graphics g) { super.paint(g); // Define a cor azul g.setColor(Color.blue); // Cria um circulo na posição (50,50) do plano cartesiano com tamanho // 300x300 g.drawOval(50, 50, 300, 300); // Para cada um dos filósofos será feito um desenho for(int i = 0; i < 5; i++) { // Define a cor para cara tipo de estado if(estado[i] == 0) { g.setColor(Color.gray); mensagem = "PENSANDO"; } if(estado[i] == 1) { g.setColor(Color.yellow); mensagem = "FAMINTO"; } if(estado[i] == 2) { g.setColor(Color.green); mensagem = "COMENDO"; } // Desenha o filósofo, sua carinha e seu nome na tela // Define os planos (x,y) e posteriormente o tamanho do objeto a ser desenhado g.fillOval((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 15, 30, 30); g.setColor(Color.black); g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 5, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 5, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 5, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 5); g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 3, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i))); g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)), (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i))); g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 3, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8); g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 3, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 8, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8); g.drawString(filosofo[i].getName(), (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 25); g.drawString(mensagem, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 40); } // ATIVA A SINCRONIA Toolkit.getDefaultToolkit().sync(); // PAUSA g.dispose(); } // Método de execução da classe, onde o ambiente será rodado public void run () { // Uma execução infinita do { // Redesenha a tela repaint(); // Dorme durante um tempo para redesenhar novamente try { Thread.sleep(1000L); } catch (InterruptedException ex) { // Exibe uma mensagem de controle de erro System.out.println("ERROR>" + ex.getMessage()); } } while (true); } }
sábado, 19 de março de 2016
Jantar dos Filósofos - Resolução
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário