2.1 - Classe BufferSincronizado.java
package br.aiec.multithread.monitor;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import br.aiec.multithread.comum.IBuffer;
/**
* Essa classe representa um monitor de fato, e, portanto,
*
* ELA É SEGURA PARA MULTITHREAD!
*
* Essa classe oferece um mecanismo de sincronização para acesso
* concorrente/paralelo ao buffer, o que consequentemente, irá garantir a
* integridade no buffer.
*
*
*
*
*/
public class BufferSincronizado implements IBuffer {
// Variáveis utilizadas garantir o acesso exclusivo
private Lock bloqueio;
private boolean cheio; // essa variável do tipo boolean representa o mutex
// Variáveis utilizadas para guardar os sinais e
// permitir transitar as threads entre os estados de executável
// e espera e vice-versa
private Condition podeGravar;
private Condition podeLer;
// Variável compartilhada
private int buffer;
public BufferSincronizado() {
bloqueio = new ReentrantLock();
podeGravar = bloqueio.newCondition();
podeLer = bloqueio.newCondition();
// Essas duas inicializações abaixo são desnecessárias, pois o Java já
// faria isso!
// Foram escritas apenas para tornar o código mais claro!
cheio = false;
buffer = 0;
}
@Override
public void gravar(int value) {
try {
bloqueio.lock();
while (cheio) {
System.out.println("Produtor esperando... Buffer cheio!");
podeGravar.await();
}
System.out.println("GRAVANDO: " + value);
this.buffer = value;
this.cheio = true;
podeLer.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bloqueio.unlock();
}
}
@Override
public int ler() {
int value = 0;
try {
bloqueio.lock();
while (!cheio) {
System.out.println("Consumidor esperando... Buffer vazio!");
podeLer.await();
}
System.out.println("LENDO: " + this.buffer);
value = this.buffer;
this.cheio = false;
podeGravar.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bloqueio.unlock();
}
return value;
}
}