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

Desenvolva um programa formado por dois processos concorrentes (threads), chamados leitor e impressor, que executam uma repetição infinita e sincronizam suas ações com o uso de semáforos. O processo leitor fica lendo caracteres do teclado e colocando em um buffer de n posições. Quando o buffer está cheio ou o caractere de quebra de linha for encontrado ('\n') o processo impressor deve imprimir o conteúdo do buffer.

 

Arquivo Buffer.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.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 copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

import java.util.concurrent.Semaphore;

/**
 * Classe responsavel pela representacao do buffer compartilhado
 */
public class Buffer
{
  /**
   * Buffer compartilhado
   */
  private String buffer;

  /**
   * Capacidade maxima do buffer
   */
  private int capacity;

  /**
   * Semafaro do leitor
   */
  private Semaphore semaphoreReader;

  /**
   * Semafaro do impressor
   */
  private Semaphore semaphoreWriter;

  /**
   * Indicacao de que a aplicacao esta em execucao
   */
  private boolean working;

  /**
   * Inicializar a capacidade maxima do buffer
   *
   * @param capacity capacidade maxima do buffer
   */
  public Buffer(int capacity)
  {
    if(capacity > 0)
    {
      this.capacity = capacity;
    }
    else
    {
      this.capacity = 10;
    }

    buffer = "";

    semaphoreReader = new Semaphore(1);

    semaphoreWriter = new Semaphore(1);

    working = true;
  }

  /**
   * Retornar se a aplicacao esta em execucao
   *
   * @return se a aplicacao esta em execucao
   */
  public boolean isWorking()
  {
    return working;
  }

  /**
   * Retornar os caracteres armazenados no buffer
   *
   * @return caracteres armazenados no buffer
   */
  public String get()
  {
    String cache = null;

    try
    {
      semaphoreWriter.acquire();

      if((buffer.length() >= capacity) || (buffer.indexOf('$') > 0))
      {
        cache = buffer;

        buffer = "";
      }
    }
    catch(InterruptedException exception)
    {
      exception.printStackTrace();
    }
    finally
    {
      semaphoreReader.release();      
    }

    return cache;
  }

  /**
   * Adicionar um caractere ao buffer
   *
   * @param character caractere a ser inserido no buffer
   */
  public  void set(char character)
  {
    try
    {
      semaphoreReader.acquire();

      if(character != '#')
      {
        buffer = buffer + character;
      }
      else
      {
        working = false;
      }
    }
    catch(InterruptedException exception)
    {
      exception.printStackTrace();
    }
    finally
    {
      semaphoreWriter.release();      
    }
  }
}

Arquivo Reader.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.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 copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

/**
 * Classe responsavel pela representacao do leitor
 */
public class Reader extends Thread
{
  /**
   * Buffer compartilhado
   */
  private Buffer buffer;

  /**
   * Construtor para inicializar o buffer compartilhado
   *
   * @param buffer buffer compartilhado
   */
  public Reader(Buffer buffer)
  {
    this.buffer = buffer;
  }

  /* (non-Javadoc)
   * @see java.lang.Thread#run()
   */
  public void run()
  {
    /*
     * $ - nova linha (\n)
     * # - fim da entrada (eof)
     */
    String scanner = "123456$789$#";

    while(buffer.isWorking())
    {
      char character = scanner.charAt(0);

      scanner = scanner.substring(1);

      buffer.set(character);

      System.out.println("Reader: " + character);

      try
      {
        sleep(100);
      }
      catch(InterruptedException exception)
      {
        exception.printStackTrace();
      }
    }
  }
}

Arquivo Writer.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.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 copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

/**
 * Classe responsavel pela representacao do impressor
 */
public class Writer extends Thread
{
  /**
   * Buffer compartilhado
   */
  private Buffer buffer;

  /**
   * Construtor para inicializar o buffer compartilhado
   *
   * @param buffer buffer compartilhado
   */
  public Writer(Buffer buffer)
  {
    this.buffer = buffer;
  }

  /* (non-Javadoc)
   * @see java.lang.Thread#run()
   */
  public void run()
  {
    while(buffer.isWorking())
    {
      String text = buffer.get();

      if(text != null)
      {
        System.out.println("Writer: " + text);
      }

      try
      {
        sleep(100);
      }
      catch(InterruptedException exception)
      {
        exception.printStackTrace();
      }
    }
  }
}

Arquivo Application.java

/**
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)
 *                  Ybadoo - Solucoes em Software Livre (www.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 copy of the license is included in the section entitled "GNU
 * Free Documentation License".
 */

package com.ybadoo.tutoriais.poo;

/**
 * Classe responsavel pela execucao das Threads
 */
public class Application
{
  /**
   * Metodo principal da linguagem de programacao Java
   *
   * @param args argumentos da linha de comando (nao utilizado)
   */
  public static void main(String[] args)
  {
    Buffer buffer = new Buffer(4);

    Reader reader = new Reader(buffer);

    Writer writer = new Writer(buffer);

    reader.start();

    writer.start();

    try
    {
      reader.join();

      writer.join();
    }
    catch(InterruptedException exception)
    {
      exception.printStackTrace();
    }
  }
}

Saída

Reader: 1
Reader: 2
Reader: 3
Reader: 4
Writer: 1234
Reader: 5
Reader: 6
Reader: $
Writer: 56$
Reader: 7
Reader: 8
Reader: 9
Reader: $
Writer: 789$
Reader: #