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.
/*************************************************************************
* 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);
}
}
/*************************************************************************
* 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);
}
}
/*************************************************************************
* 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();
}
}
/*************************************************************************
* 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();
}
}
}
}
/*************************************************************************
* 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();
}
}
}
}
/*************************************************************************
* 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();
}
}