Edited code:
import java.util.concurrent.atomic.AtomicBoolean;
public class ProducerConsumer
{
public static final int bufferSize = 6;
private static CircularBuffer buffer = new CircularBuffer (bufferSize);
public static void main (String[] args)
{
if ( args.length != 1 ) {
String className = ProductorConsumidor.class.getSimpleName();
throw new RuntimeException ("Usage: java " + className + " number");
}
int numElems = Integer.parseInt (args[0]);
Consumer consumer = new Consumer (buffer, numElems);
Producer producer = new Producer (buffer, numElems);
consumer.start(); producer.start();
}
public static class Peterson
{
private static volatile int turn;
private static AtomicBoolean[] flag = { new AtomicBoolean(),
new AtomicBoolean() };
private int id;
public Peterson (int i)
{
id = i;
}
private int other ()
{
return id == 0 ? 1 : 0;
}
public void lock ()
{
flag[id].set (true);
turn = other ();
while ( turn == other() && flag[other()].get() )
Thread.yield ();
}
public void unlock ()
{
flag[id].set (false);
turn = other ();
}
}
public static class CircularBuffer
{
private volatile int[] elem;
private volatile int nElems;
private int producerPosition;
private int consumerPosition;
private Peterson pt0 = new Peterson (0);
private Peterson pt1 = new Peterson (1);
public CircularBuffer (int bufferSize)
{
elem = new int[bufferSize];
producerPosition = 0;
consumerPosition = 0;
nElems = 0;
}
public void produce (int element)
{
while ( nElems == bufferSize )
; // wait while full
produceNewElement (element);
}
public void produceNewElement (int element)
{
pt0.lock ();
elem[producerPosition] = element;
producerPosition = (producerPosition + 1) % bufferSize;
++nElems;
pt0.unlock ();
}
public int consume ()
{
while ( nElems == 0 )
; // wait while empty
return consumeNewElement ();
}
public int consumeNewElement ()
{
pt1.lock ();
int ret;
ret = elem[consumerPosition];
consumerPosition = (consumerPosition + 1) % bufferSize;
--nElems;
pt1.unlock ();
return ret;
}
}
public static class Producer extends Thread
{
private CircularBuffer buffer;
private int numElems;
public Producer (CircularBuffer b, int m)
{
buffer = b;
numElems = m;
}
@Override
public void run ()
{
for ( int i = 0; i < numElems; ++i ) {
buffer.produce (i);
}
}
}
public static class Consumer extends Thread
{
private CircularBuffer buffer;
private int numElems;
public Consumer (CircularBuffer b, int m)
{
buffer = b;
numElems = m;
}
@Override
public void run ()
{
int data, previousData;
data = buffer.consume ();
for ( int i = 0; i < numElems - 1; ++i ) {
System.out.printf (data + " ");
previousData = data;
data = buffer.consume ();
if ( previousData > data )
throw new RuntimeException ("Incorrect data order");
}
System.out.printf (data + " ");
}
}
}
Original code: