package uk.ac.imperial.lsds.seep.integration.performance.microbenchmarks;
import java.nio.ByteBuffer;
public class ProducerConsumerTest {
public static void main(String args[]){
Buffer b = new Buffer(6);
Thread p = new Thread(new Producer(b));
Thread c = new Thread(new Consumer(b));
c.start();
p.start();
while(true);
}
}
class Producer implements Runnable{
private boolean working = true;
private Buffer b;
public void stop(){
working = false;
}
public Producer(Buffer b){
this.b = b;
}
@Override
public void run(){
byte a = 0,b = 0,c = 0;
while(working){
byte[] data = new byte[] { a, b, c, (byte) (a*2), (byte) (b*2), (byte) (c*2)};
a++; b++; c++;
this.b.add(data); // will block if there's not enough space
}
}
}
class Consumer implements Runnable{
private boolean working = true;
private Buffer b;
public void stop(){
working = false;
}
public Consumer(Buffer b){
this.b = b;
}
@Override
public void run(){
int counter = 0;
long time = System.currentTimeMillis();
while(working){
byte[] data = b.poll();
counter++;
long elapsedTime = (System.currentTimeMillis()-time);
if(elapsedTime > 1000){
System.out.println("r/s: "+counter);
counter = 0;
time = System.currentTimeMillis();
}
}
}
}
class Buffer{
private ByteBuffer buf;
private boolean completed;
public Buffer(int batchSize){
buf = ByteBuffer.allocate(batchSize);
}
public void add(byte[] data){
if(completed) waitHere(); // block
if(enoughSpaceInBuffer(data.length)) buf.put(data);
else completed = true;
}
public byte[] poll(){
byte[] data = null;
if(completed){
buf.flip();
data = new byte[6];
if(buf.remaining() > 6){
buf.get(data, 0, 6);
}
else{ // finished reading all batch
completed = false;
buf.clear();
notifyHere();
}
}
return data;
}
private boolean enoughSpaceInBuffer(int size){
return buf.remaining() > size;
}
private void notifyHere(){
synchronized(this){
notify();
}
}
private void waitHere(){
try {
synchronized(this){
wait();
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}