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);
}
}
Comentários
Postar um comentário