Ybadoo - Soluções em Software Livre
Tutoriais
Programação Orientada a Objetos

Desenvolva um programa concorrente formado por três threads, uma consumidora e duas produtoras, que executam uma repetição eterna. A thread consumidora recebe informações (um valor inteiro) da thread produtora1 no buffer1 e da thread produtora2 no buffer2 (primeiro consome do buffer1 e depois consome do buffer2). Os buffers possuem capacidade de armazenar um único elemento. A thread consumidora somente pode consumir se existirem informações no buffer e as threads produtoras somente podem voltar a produzir depois da thread consumidora haver retirado as informações do buffer.

 

Terminal

ybadoo@server:~$ ./application
Diagrama de Classes na Linguagem de Programação Java EmptyBufferException.java FullBufferException.java Buffer.java Producer.java Consumer.java Application.java
Diagrama de Classes
Diagrama de Classes na Linguagem de Programação Java

Arquivo EmptyBufferException.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

/**
 * Excecao lancada pela classe Buffer para indicar que o buffer esta vazio
 */
public class EmptyBufferException extends RuntimeException
{
  /**
   * Identificador de serializacao da classe
   */
  private static final long serialVersionUID = 1L;

  /**
   * Construtor padrao
   */
  public EmptyBufferException()
  {
    super();
  }

  /**
   * Construtor para inicializar a mensagem de erro
   *
   * @param message mensagem de erro
   */
  public EmptyBufferException(String message)
  {
    super(message);
  }

  /**
   * Construtor para inicializar a mensagem de erro e a causa do erro
   *
   * @param message mensagem de erro
   * @param cause causa do erro
   */
  public EmptyBufferException(String message, Throwable cause)
  {
    super(message, cause);
  }

  /**
   * Construtor para inicializar a mensagem de erro, a causa do erro,
   * a supressao e o rastreamento da pilha
   *
   * @param message mensagem de erro
   * @param cause causa do erro
   * @param enableSuppression se a supressao esta ativada ou desativada
   * @param writableStackTrace se o rastreamento da pilha deve ser gravavel
   */
  public EmptyBufferException(String message, Throwable cause,
    boolean enableSuppression, boolean writableStackTrace)
  {
    super(message, cause, enableSuppression, writableStackTrace);
  }

  /**
   * Construtor para inicializar a causa do erro
   *
   * @param cause causa do erro
   */
  public EmptyBufferException(Throwable cause)
  {
    super(cause);
  }
}

Arquivo FullBufferException.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

/**
 * Excecao lancada pela classe Buffer para indicar que o buffer esta cheio
 */
public class FullBufferException extends RuntimeException
{
  /**
   * Identificador de serializacao da classe
   */
  private static final long serialVersionUID = 1L;

  /**
   * Construtor padrao
   */
  public FullBufferException()
  {
    super();
  }

  /**
   * Construtor para inicializar a mensagem de erro
   *
   * @param message mensagem de erro
   */
  public FullBufferException(String message)
  {
    super(message);
  }

  /**
   * Construtor para inicializar a mensagem de erro e a causa do erro
   *
   * @param message mensagem de erro
   * @param cause causa do erro
   */
  public FullBufferException(String message, Throwable cause)
  {
    super(message, cause);
  }

  /**
   * Construtor para inicializar a mensagem de erro, a causa do erro,
   * a supressao e o rastreamento da pilha
   *
   * @param message mensagem de erro
   * @param cause causa do erro
   * @param enableSuppression se a supressao esta ativada ou desativada
   * @param writableStackTrace se o rastreamento da pilha deve ser gravavel
   */
  public FullBufferException(String message, Throwable cause,
    boolean enableSuppression, boolean writableStackTrace)
  {
    super(message, cause, enableSuppression, writableStackTrace);
  }

  /**
   * Construtor para inicializar a causa do erro
   *
   * @param cause causa do erro
   */
  public FullBufferException(Throwable cause)
  {
    super(cause);
  }
}

Arquivo Buffer.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

import java.io.Serializable;

/**
 * Buffer de inteiros compartilhado pelo produtor e consumidor
 */
public class Buffer implements Serializable
{
  /**
   * Identificador de serializacao da classe
   */
  private static final long serialVersionUID = 1L;

  /**
   * Nome do buffer
   */
  private String name;

  /**
   * Valor inteiro
   */
  private Integer value;

  /**
   * Construtor para inicializar o buffer
   */
  public Buffer(String name)
  {
    this.name = name;

    value = null;
  }

  /**
   * Retornar o nome do buffer
   *
   * @return nome do buffer
   */
  public String getName()
  {
    return name;
  }

  /**
   * Verificar se o buffer esta vazio
   *
   * @return true se o buffer esta vazio, false em caso contrario
   */
  public boolean isEmpty()
  {
    return value == null;
  }

  /**
   * Verificar se o buffer esta cheio
   *
   * @return true se o buffer esta cheio, false em caso contrario
   */
  public boolean isFull()
  {
    return value != null;
  }

  /**
   * Inserir um novo valor no buffer
   *
   * @param value novo valor
   * @throws FullBufferException buffer cheio
   */
  public void add(Integer value) throws FullBufferException
  {
    if(!isFull())
    {
      this.value = value;
    }
    else
    {
      throw new FullBufferException();
    }
  }

  /**
   * Remover o valor do buffer
   *
   * @return valor do buffer
   * @throws EmptyBufferException buffer vazio
   */
  public Integer remove() throws EmptyBufferException
  {
    if(!isEmpty())
    {
      Integer aux = value;

      value = null;

      return aux;
    }

    throw new EmptyBufferException();
  }
}

Arquivo Producer.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

import java.util.concurrent.ThreadLocalRandom;

/**
 * Produtor de elementos inteiros
 */
public class Producer implements Runnable
{
  /**
   * Buffer de inteiros
   */
  private Buffer buffer;

  /**
   * Nome do produtor
   */
  private String name;

  /**
   * Construtor para inicializar o produtor
   *
   * @param name nome do produtor
   * @param buffer buffer de inteiros
   */
  public Producer(String name, Buffer buffer)
  {
    this.name = name;

    this.buffer = buffer;
  }

  /* (non-Javadoc)
   * @see java.lang.Runnable#run()
   */
  @Override
  public void run()
  {
    ThreadLocalRandom random = ThreadLocalRandom.current();

    while(true)
    {
      try
      {
        synchronized(buffer)
        {
          while(buffer.isFull())
          {
            System.out.print(name + ": ");
            System.out.println(buffer.getName() + " is full!");

            buffer.wait();
          }

          Integer value = random.nextInt(100);

          buffer.add(value);

          System.out.print(name + ": produced " + value);
          System.out.println(" to the " + buffer.getName());

          buffer.notifyAll();
        }
      }
      catch(InterruptedException exception)
      {
        exception.printStackTrace();
      }
    }
  }
}

Arquivo Consumer.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

import java.util.List;

/**
 * Consumidor de elementos inteiros
 */
public class Consumer implements Runnable
{
  /**
   * Lista de buffer de inteiros
   */
  private List<Buffer> buffers;

  /**
   * Nome do consumidor
   */
  private String name;

  /**
   * Construtor para inicializar o consumidor
   *
   * @param name nome do consumidor
   * @param buffers lista de buffer de inteiros
   */
  public Consumer(String name, List<Buffer> buffers)
  {
    this.name = name;

    this.buffers = buffers;
  }

  /* (non-Javadoc)
   * @see java.lang.Runnable#run()
   */
  @Override
  public void run()
  {
    while(true)
    {
      try
      {
        for(Buffer buffer: buffers)
        {
          synchronized(buffer)
          {
            while(buffer.isEmpty())
            {
              System.out.print(name + ": ");
              System.out.println(buffer.getName() + " is empty!");

              buffer.wait();
            }

            Integer value = buffer.remove();

            System.out.print(name + ": consumed " + value);
            System.out.println(" from the " + buffer.getName());

            buffer.notifyAll();
          }
        }
      }
      catch(InterruptedException exception)
      {
        exception.printStackTrace();
      }
    }
  }
}

Arquivo Application.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial06.exercicio06;

import java.util.LinkedList;
import java.util.List;

/**
 * Classe responsavel pela execucao da solucao
 */
public class Application
{
  /**
   * Construtor para inicializar a execucao da solucao
   */
  private Application()
  {

  }

  /**
   * Metodo principal da linguagem de programacao Java
   *
   * @param args argumentos da linha de comando (nao utilizado)
   */
  public static void main(String[] args)
  {
    List<Buffer> buffers = new LinkedList<Buffer>();

    buffers.add(new Buffer("buffer 01"));
    buffers.add(new Buffer("buffer 02"));

    new Thread(new Producer("Producer 01", buffers.get(0))).start();

    new Thread(new Producer("Producer 02", buffers.get(1))).start();

    new Thread(new Consumer("Consumer 01", buffers)).start();
  }
}