Problems with Traffic Lights (Producer / Consumer)

1

Hello! I am trying to solve the Problem of the Producer / Consumer using traffic lights, but I am having difficulties. I'm using one producer thread and one consumer thread, but I think the program is initializing the producer and not doing the same with the consumer. Could you tell me where the problem is? Many thanks!

//Classe Principal
public class Principal {      

  public static void main(String[] args) {
    int N = 100;
    Semaphore mutex = new Semaphore(1);
    Semaphore vazio = new Semaphore(N);
    Semaphore cheio = new Semaphore(0);
    Fila fl = new Fila();

    Produtor produtor = new Produtor(mutex, vazio, cheio, fl);
    Consumidor consumidor = new Consumidor(mutex, vazio, cheio, fl);

    produtor.run();
    consumidor.run();
  }
}

//Classe do Produtor
public class Produtor extends Thread {
  Fila fl;
  Semaphore mutex, vazio, cheio;

  public Produtor(Semaphore mutex, Semaphore vazio, Semaphore cheio, Fila fl){
    this.mutex = mutex;
    this.vazio = vazio;
    this.cheio = cheio;
    this.fl = fl;
}

public void run(){
    int item;        
    while(true){
        try {
            Thread.sleep( ( int ) ( Math.random() * 3000 ) );
        } catch (InterruptedException ex) {
            Logger.getLogger(Produtor.class.getName()).log(Level.SEVERE, null, ex);
        }
        item = aleatorio(0, 99);
        this.vazio.down();
        this.mutex.down();
        this.fl.insere(item);
        this.mutex.up();
        this.cheio.up();
    }

}

  public int aleatorio(int minimo, int maximo) {
    Random random = new Random();
    return random.nextInt((maximo - minimo) + 1) + minimo;
  }
}

//Classe do Consumidor
public class Consumidor extends Thread {
  Fila fl;
  Semaphore mutex, vazio, cheio;

  public Consumidor(Semaphore mutex, Semaphore vazio, Semaphore cheio, Fila fl){
    this.mutex = mutex;
    this.vazio = vazio;
    this.cheio = cheio;
    this.fl = fl;
}

public void run() {
    int item;        
    while(true){
        try {
            Thread.sleep( ( int ) ( Math.random() * 3000 ) );
        } catch (InterruptedException ex) {
            Logger.getLogger(Consumidor.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.cheio.down();
        this.mutex.down();
        item = (int)this.fl.remove();
        this.mutex.up();
        this.vazio.up();
        System.out.println(item);
    }
  }
} 

//Classe do Semáforo
public class Semaphore {
  private int count = 0;

  public Semaphore(int initVal) {
    count = initVal;
  }

  public synchronized void down() {
    if (count > 0){
        count--;
    } else {
        try {        /* esperar até que count > 0 */
            wait();
        } catch (InterruptedException e) { 
            System.out.println("erro");
        }  
    }

  }

  public synchronized void up() {
    count++;
    notify(); /* acordar quem estiver em espera */
  } 
}

//Classe Fila para armazenar os elemenetos
public class Fila<T> {
  private List<T> objetos = new LinkedList<T>();

  public void insere(T t){
    this.objetos.add(t);
  }

  public T remove(){
    return this.objetos.remove(0);
  }

  public boolean vazia(){
    return this.objetos.size() == 0;
  }
}
    
asked by anonymous 11.10.2017 / 13:45

1 answer

2

This is executing the thread by the run method, that is, it will execute the code of this method on the current thread without creating a new thread (like any other method). Therefore, the% of consumer% will only execute when run of the producer is finished, ie never in this example.

You should use the run method that creates a new thread and runs start on this new thread, returning run on the current thread:

public static void main(String[] args) {
    ...
    produtor.start();   // executa o run numa nova thread
    consumidor.start();
}

Additional information : instead of extending the thread it is more appropriate to implement Runnable and pass it to the thread constructor:

class Produtor implementes Runnable {
    ...
    public void run() {
        ...
    }
}

Usage:

    Produtor produtor = new Produtor(...);
    Thead produtorThread = new Thread(produtor(;
    produtorThread.start();

More information: Threads

    
11.10.2017 / 22:20