Pessoal, estou começando o estudo sobre threads na facul, estamos implementando junto com o professor esse programinha que utiliza duas threads para a escrita e leitura dos valores que estão no vetor.
Bom minha duvida é uma questão que o professor levantou na ultima aula:
Por que o código teria problemas caso o WHILE da da linha 27 do método gravar() da classe BufferCircular fosse trocado por um IF, e a mesma pergunta pra Troca do WHILE da linha
53 do método ler().
Sei a diferença de WHILE e IF, mas nao soube explicar o porque do prejuízo caso houvesse a troca!
Alguém tem alguma ideia?
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class CircularBuffer implements IBuffer{
private int valores[];
private int r;
private int w;
private int quantidade;
private Lock bloqueio = new ReentrantLock();
private Condition podeGravar = bloqueio.newCondition();
private Condition podeLer = bloqueio.newCondition();
public CircularBuffer(int tamanho){
valores = new int[tamanho];
w = 0;
r = 0;
quantidade = 0;
}
@Override
public void gravar(int valor) {
bloqueio.lock();
while(quantidade == valores.length){
try {
System.out.println("Produtor esperando....");
podeGravar.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Gravando: " + valor);
this.valores[w] = valor;
w = (w + 1) % valores.length;
quantidade++;
podeLer.signal();
bloqueio.unlock();
}
@Override
public int ler() {
int auxiliar = 0;
bloqueio.lock();
while(quantidade == 0){
try {
System.out.println("Consumidor esperando....");
podeLer.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Lendo: " + valores[r]);
auxiliar = valores[r];
r = (r + 1) % valores.length;
quantidade--;
podeGravar.signal();
bloqueio.unlock();
return auxiliar;
}
}
A classe que controla a escrita:
import java.util.Random;
public class Produtor implements Runnable{
private IBuffer buffer;
public Produtor(IBuffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
int somatorio = 0;
for(int i = 1; i <=1000000; i++){
buffer.gravar(i);
somatorio += i;
//esperaCronometrada();
}
System.out.println("Produtor escreveu: " + somatorio);
}
private void esperaCronometrada() {
try {
Random r = new Random();
Thread.sleep(r.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Classe que controla a leitura:
public class Consumidor implements Runnable{
private IBuffer buffer;
public Consumidor(IBuffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
int somatorio = 0;
for(int i = 1; i <=1000000; i++){
somatorio += buffer.ler();
//esperaCronometrada();
}
System.out.println("Consumidor leu: " + somatorio);
}
private void esperaCronometrada() {
try {
Random r = new Random();
Thread.sleep(r.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Classe do main:
package br.upis.tu382;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Principal {
public static void main(String[] args) {
ExecutorService pool;
pool = Executors.newFixedThreadPool(2);
IBuffer buffer = new CircularBuffer(5);
Runnable produtor = new Produtor(buffer);
Runnable consumidor = new Consumidor(buffer);
pool.execute(produtor);
pool.execute(consumidor);
pool.shutdown();
}
}