Skip to main content
added 4868 characters in body
Source Link
user61445
user61445

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:

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:

deleted 4 characters in body; edited tags
Source Link
200_success
  • 145.7k
  • 22
  • 191
  • 481

    import  java.util.concurrent.atomic.AtomicBoolean;
    
    public class  ProducerConsumer
    {
        public static void  main (String[]  args)
        {
            if ( args.length != 1 ) {
                throw new  RuntimeException ("Usage: fileName number");
            }
            int         N     = 6;  // Size of circular buffer
            int         max   = Integer.parseInt (args[0]);  // number of elements to produce
            CircularBuffer  buf = new  CircularBuffer (N);
            Consumer    cons  = new  Consumer (buf, max);
            Producer    produ = new  Producer (buf, max);
    
            cons.start(); produ.start();
        }
    
        public static class  Peterson
        {
            private volatile int  turn;
            private AtomicBoolean[]  flag = new  AtomicBoolean[2];
            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[id].get() )
                    Thread.yield ();
            }
    
            public void  unlock ()
            {
                flag[id].set (false);
                turn = other ();
            }
        }
    
        public static class  CircularBuffer
        {
            private volatile int[]  elem;
            private volatile int    nelem;          // control elements in buffer
            private int  p;                         // consumer position
            private int  c;                         // producer position
            private Peterson  pt0 = new  Peterson (0);
            private Peterson  pt1 = new  Peterson (1);
    
            // Shared circular buffer
            public  CircularBuffer (int  N)
            {
                elem  = new  int[N];
                p     = 0;
                c     = 0;
                nelem = 0;
            }
    
            public void  produce (int  e)
            {
                while ( nelem == elem.length );     // while full
                pt0.lock ();                        // lock
                elem[p] = e;                        // produce new element
                p = (p + 1) % elem.length;          // new position in the circular array
                ++nelem;                            // increment number of elements in the shared buffer
                pt0.unlock ();                      // unlock
            }
    
            public int  consume ()
            {
                while ( nelem == 0 );               // while empty
                pt1.lock ();                        // lock
                int  ret;                           // variable to return
                ret = elem[c];                      // assignment
                c = (c + 1) % elem.length;          // new position in the circular array
                --nelem;                            // decrement number of elements in the shared buffer
                pt1.unlock ();                      // unlock
    
                return  ret;
            }
        }
    
        public static class  Producer extends Thread
        {
            private CircularBuffer  buf;
            private int     max;
    
            public  Producer (CircularBuffer  b, int  m)
            {
                buf = b;
                max = m;
            }
    
            public void  run ()
            {
                for ( int i = 0;  i  data )
                        throw new  RuntimeException ("Incorrect data order");
                }
                System.out.printf (data + " ");
            }
        }
    }
import  java.util.concurrent.atomic.AtomicBoolean;

public class  ProducerConsumer
{
    public static void  main (String[]  args)
    {
        if ( args.length != 1 ) {
            throw new  RuntimeException ("Usage: fileName number");
        }
        int         N     = 6;  // Size of circular buffer
        int         max   = Integer.parseInt (args[0]);  // number of elements to produce
        CircularBuffer  buf = new  CircularBuffer (N);
        Consumer    cons  = new  Consumer (buf, max);
        Producer    produ = new  Producer (buf, max);

        cons.start(); produ.start();
    }

    public static class  Peterson
    {
        private volatile int  turn;
        private AtomicBoolean[]  flag = new  AtomicBoolean[2];
        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[id].get() )
                Thread.yield ();
        }

        public void  unlock ()
        {
            flag[id].set (false);
            turn = other ();
        }
    }

    public static class  CircularBuffer
    {
        private volatile int[]  elem;
        private volatile int    nelem;          // control elements in buffer
        private int  p;                         // consumer position
        private int  c;                         // producer position
        private Peterson  pt0 = new  Peterson (0);
        private Peterson  pt1 = new  Peterson (1);

        // Shared circular buffer
        public  CircularBuffer (int  N)
        {
            elem  = new  int[N];
            p     = 0;
            c     = 0;
            nelem = 0;
        }

        public void  produce (int  e)
        {
            while ( nelem == elem.length );     // while full
            pt0.lock ();                        // lock
            elem[p] = e;                        // produce new element
            p = (p + 1) % elem.length;          // new position in the circular array
            ++nelem;                            // increment number of elements in the shared buffer
            pt0.unlock ();                      // unlock
        }

        public int  consume ()
        {
            while ( nelem == 0 );               // while empty
            pt1.lock ();                        // lock
            int  ret;                           // variable to return
            ret = elem[c];                      // assignment
            c = (c + 1) % elem.length;          // new position in the circular array
            --nelem;                            // decrement number of elements in the shared buffer
            pt1.unlock ();                      // unlock

            return  ret;
        }
    }

    public static class  Producer extends Thread
    {
        private CircularBuffer  buf;
        private int     max;

        public  Producer (CircularBuffer  b, int  m)
        {
            buf = b;
            max = m;
        }

        public void  run ()
        {
            for ( int i = 0;  i < max;  ++i ) {
                buf.produce (i);
            }
        }
    }

    public static class  Consumer extends Thread
    {
        private CircularBuffer  buf;
        private int     max;

        public  Consumer (CircularBuffer  b, int  m)
        {
            buf = b;
            max = m;
        }

        public void  run ()
        {
            int  data, previousData;

            data = buf.consume ();
            for ( int i = 0;  i < max - 1;  ++i ) {
                System.out.printf (data + " ");
                previousData = data;
                data = buf.consume ();
                if ( previousData > data )
                    throw new  RuntimeException ("Incorrect data order");
            }
            System.out.printf (data + " ");
        }
    }
}

    import  java.util.concurrent.atomic.AtomicBoolean;
    
    public class  ProducerConsumer
    {
        public static void  main (String[]  args)
        {
            if ( args.length != 1 ) {
                throw new  RuntimeException ("Usage: fileName number");
            }
            int         N     = 6;  // Size of circular buffer
            int         max   = Integer.parseInt (args[0]);  // number of elements to produce
            CircularBuffer  buf = new  CircularBuffer (N);
            Consumer    cons  = new  Consumer (buf, max);
            Producer    produ = new  Producer (buf, max);
    
            cons.start(); produ.start();
        }
    
        public static class  Peterson
        {
            private volatile int  turn;
            private AtomicBoolean[]  flag = new  AtomicBoolean[2];
            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[id].get() )
                    Thread.yield ();
            }
    
            public void  unlock ()
            {
                flag[id].set (false);
                turn = other ();
            }
        }
    
        public static class  CircularBuffer
        {
            private volatile int[]  elem;
            private volatile int    nelem;          // control elements in buffer
            private int  p;                         // consumer position
            private int  c;                         // producer position
            private Peterson  pt0 = new  Peterson (0);
            private Peterson  pt1 = new  Peterson (1);
    
            // Shared circular buffer
            public  CircularBuffer (int  N)
            {
                elem  = new  int[N];
                p     = 0;
                c     = 0;
                nelem = 0;
            }
    
            public void  produce (int  e)
            {
                while ( nelem == elem.length );     // while full
                pt0.lock ();                        // lock
                elem[p] = e;                        // produce new element
                p = (p + 1) % elem.length;          // new position in the circular array
                ++nelem;                            // increment number of elements in the shared buffer
                pt0.unlock ();                      // unlock
            }
    
            public int  consume ()
            {
                while ( nelem == 0 );               // while empty
                pt1.lock ();                        // lock
                int  ret;                           // variable to return
                ret = elem[c];                      // assignment
                c = (c + 1) % elem.length;          // new position in the circular array
                --nelem;                            // decrement number of elements in the shared buffer
                pt1.unlock ();                      // unlock
    
                return  ret;
            }
        }
    
        public static class  Producer extends Thread
        {
            private CircularBuffer  buf;
            private int     max;
    
            public  Producer (CircularBuffer  b, int  m)
            {
                buf = b;
                max = m;
            }
    
            public void  run ()
            {
                for ( int i = 0;  i  data )
                        throw new  RuntimeException ("Incorrect data order");
                }
                System.out.printf (data + " ");
            }
        }
    }
import  java.util.concurrent.atomic.AtomicBoolean;

public class  ProducerConsumer
{
    public static void  main (String[]  args)
    {
        if ( args.length != 1 ) {
            throw new  RuntimeException ("Usage: fileName number");
        }
        int         N     = 6;  // Size of circular buffer
        int         max   = Integer.parseInt (args[0]);  // number of elements to produce
        CircularBuffer  buf = new  CircularBuffer (N);
        Consumer    cons  = new  Consumer (buf, max);
        Producer    produ = new  Producer (buf, max);

        cons.start(); produ.start();
    }

    public static class  Peterson
    {
        private volatile int  turn;
        private AtomicBoolean[]  flag = new  AtomicBoolean[2];
        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[id].get() )
                Thread.yield ();
        }

        public void  unlock ()
        {
            flag[id].set (false);
            turn = other ();
        }
    }

    public static class  CircularBuffer
    {
        private volatile int[]  elem;
        private volatile int    nelem;          // control elements in buffer
        private int  p;                         // consumer position
        private int  c;                         // producer position
        private Peterson  pt0 = new  Peterson (0);
        private Peterson  pt1 = new  Peterson (1);

        // Shared circular buffer
        public  CircularBuffer (int  N)
        {
            elem  = new  int[N];
            p     = 0;
            c     = 0;
            nelem = 0;
        }

        public void  produce (int  e)
        {
            while ( nelem == elem.length );     // while full
            pt0.lock ();                        // lock
            elem[p] = e;                        // produce new element
            p = (p + 1) % elem.length;          // new position in the circular array
            ++nelem;                            // increment number of elements in the shared buffer
            pt0.unlock ();                      // unlock
        }

        public int  consume ()
        {
            while ( nelem == 0 );               // while empty
            pt1.lock ();                        // lock
            int  ret;                           // variable to return
            ret = elem[c];                      // assignment
            c = (c + 1) % elem.length;          // new position in the circular array
            --nelem;                            // decrement number of elements in the shared buffer
            pt1.unlock ();                      // unlock

            return  ret;
        }
    }

    public static class  Producer extends Thread
    {
        private CircularBuffer  buf;
        private int     max;

        public  Producer (CircularBuffer  b, int  m)
        {
            buf = b;
            max = m;
        }

        public void  run ()
        {
            for ( int i = 0;  i < max;  ++i ) {
                buf.produce (i);
            }
        }
    }

    public static class  Consumer extends Thread
    {
        private CircularBuffer  buf;
        private int     max;

        public  Consumer (CircularBuffer  b, int  m)
        {
            buf = b;
            max = m;
        }

        public void  run ()
        {
            int  data, previousData;

            data = buf.consume ();
            for ( int i = 0;  i < max - 1;  ++i ) {
                System.out.printf (data + " ");
                previousData = data;
                data = buf.consume ();
                if ( previousData > data )
                    throw new  RuntimeException ("Incorrect data order");
            }
            System.out.printf (data + " ");
        }
    }
}
Fix the code formatting with <pre>; Needs a better solution though.
Source Link
  • There is a single consumer that will display the elements deposited in the buffer.

    import java.util.concurrent.atomic.AtomicBoolean;

    public class ProducerConsumer { public static void main (String[] args) { if ( args.length != 1 ) { throw new RuntimeException ("Usage: fileName number"); } int N = 6; // Size of circular buffer int max = Integer.parseInt (args[0]); // number of elements to produce CircularBuffer buf = new CircularBuffer (N); Consumer cons = new Consumer (buf, max); Producer produ = new Producer (buf, max);

         cons.start(); produ.start();
     }
    
     public static class  Peterson
     {
         private volatile int  turn;
         private AtomicBoolean[]  flag = new  AtomicBoolean[2];
         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[id].get() )
                 Thread.yield ();
         }
    
         public void  unlock ()
         {
             flag[id].set (false);
             turn = other ();
         }
     }
    
     public static class  CircularBuffer
     {
         private volatile int[]  elem;
         private volatile int    nelem;          // control elements in buffer
         private int  p;                         // consumer position
         private int  c;                         // producer position
         private Peterson  pt0 = new  Peterson (0);
         private Peterson  pt1 = new  Peterson (1);
    
         // Shared circular buffer
         public  CircularBuffer (int  N)
         {
             elem  = new  int[N];
             p     = 0;
             c     = 0;
             nelem = 0;
         }
    
         public void  produce (int  e)
         {
             while ( nelem == elem.length );     // while full
             pt0.lock ();                        // lock
             elem[p] = e;                        // produce new element
             p = (p + 1) % elem.length;          // new position in the circular array
             ++nelem;                            // increment number of elements in the shared buffer
             pt0.unlock ();                      // unlock
         }
    
         public int  consume ()
         {
             while ( nelem == 0 );               // while empty
             pt1.lock ();                        // lock
             int  ret;                           // variable to return
             ret = elem[c];                      // assignment
             c = (c + 1) % elem.length;          // new position in the circular array
             --nelem;                            // decrement number of elements in the shared buffer
             pt1.unlock ();                      // unlock
    
             return  ret;
         }
     }
    
     public static class  Producer extends Thread
     {
         private CircularBuffer  buf;
         private int     max;
    
         public  Producer (CircularBuffer  b, int  m)
         {
             buf = b;
             max = m;
         }
    
         public void  run ()
         {
             for ( int i = 0;  i < max;  ++i ) {
                 buf.produce (i);
             }
         }
     }
    
     public static class  Consumer extends Thread
     {
         private CircularBuffer  buf;
         private int     max;
    
         public  Consumer (CircularBuffer  b, int  m)
         {
             buf = b;
             max = m;
         }
    
         public void  run ()
         {
             int  data, previousData;
    
             data = buf.consume ();
             for ( int i = 0;  i < max - 1;  ++i ) {
                 System.out.printf (data + " ");
                 previousData = data;
                 data = buf.consume ();
                 if ( previousData > data )
                     throw new  RuntimeException ("Incorrect data order");
             }
             System.out.printf (data + " ");
         }
     }
    

    }

    There is a single consumer that will display the elements deposited in the buffer.

    import  java.util.concurrent.atomic.AtomicBoolean;
    
    public class  ProducerConsumer
    {
        public static void  main (String[]  args)
        {
            if ( args.length != 1 ) {
                throw new  RuntimeException ("Usage: fileName number");
            }
            int         N     = 6;  // Size of circular buffer
            int         max   = Integer.parseInt (args[0]);  // number of elements to produce
            CircularBuffer  buf = new  CircularBuffer (N);
            Consumer    cons  = new  Consumer (buf, max);
            Producer    produ = new  Producer (buf, max);
    
            cons.start(); produ.start();
        }
    
        public static class  Peterson
        {
            private volatile int  turn;
            private AtomicBoolean[]  flag = new  AtomicBoolean[2];
            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[id].get() )
                    Thread.yield ();
            }
    
            public void  unlock ()
            {
                flag[id].set (false);
                turn = other ();
            }
        }
    
        public static class  CircularBuffer
        {
            private volatile int[]  elem;
            private volatile int    nelem;          // control elements in buffer
            private int  p;                         // consumer position
            private int  c;                         // producer position
            private Peterson  pt0 = new  Peterson (0);
            private Peterson  pt1 = new  Peterson (1);
    
            // Shared circular buffer
            public  CircularBuffer (int  N)
            {
                elem  = new  int[N];
                p     = 0;
                c     = 0;
                nelem = 0;
            }
    
            public void  produce (int  e)
            {
                while ( nelem == elem.length );     // while full
                pt0.lock ();                        // lock
                elem[p] = e;                        // produce new element
                p = (p + 1) % elem.length;          // new position in the circular array
                ++nelem;                            // increment number of elements in the shared buffer
                pt0.unlock ();                      // unlock
            }
    
            public int  consume ()
            {
                while ( nelem == 0 );               // while empty
                pt1.lock ();                        // lock
                int  ret;                           // variable to return
                ret = elem[c];                      // assignment
                c = (c + 1) % elem.length;          // new position in the circular array
                --nelem;                            // decrement number of elements in the shared buffer
                pt1.unlock ();                      // unlock
    
                return  ret;
            }
        }
    
        public static class  Producer extends Thread
        {
            private CircularBuffer  buf;
            private int     max;
    
            public  Producer (CircularBuffer  b, int  m)
            {
                buf = b;
                max = m;
            }
    
            public void  run ()
            {
                for ( int i = 0;  i  data )
                        throw new  RuntimeException ("Incorrect data order");
                }
                System.out.printf (data + " ");
            }
        }
    }
  • There is a single consumer that will display the elements deposited in the buffer.

    import java.util.concurrent.atomic.AtomicBoolean;

    public class ProducerConsumer { public static void main (String[] args) { if ( args.length != 1 ) { throw new RuntimeException ("Usage: fileName number"); } int N = 6; // Size of circular buffer int max = Integer.parseInt (args[0]); // number of elements to produce CircularBuffer buf = new CircularBuffer (N); Consumer cons = new Consumer (buf, max); Producer produ = new Producer (buf, max);

         cons.start(); produ.start();
     }
    
     public static class  Peterson
     {
         private volatile int  turn;
         private AtomicBoolean[]  flag = new  AtomicBoolean[2];
         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[id].get() )
                 Thread.yield ();
         }
    
         public void  unlock ()
         {
             flag[id].set (false);
             turn = other ();
         }
     }
    
     public static class  CircularBuffer
     {
         private volatile int[]  elem;
         private volatile int    nelem;          // control elements in buffer
         private int  p;                         // consumer position
         private int  c;                         // producer position
         private Peterson  pt0 = new  Peterson (0);
         private Peterson  pt1 = new  Peterson (1);
    
         // Shared circular buffer
         public  CircularBuffer (int  N)
         {
             elem  = new  int[N];
             p     = 0;
             c     = 0;
             nelem = 0;
         }
    
         public void  produce (int  e)
         {
             while ( nelem == elem.length );     // while full
             pt0.lock ();                        // lock
             elem[p] = e;                        // produce new element
             p = (p + 1) % elem.length;          // new position in the circular array
             ++nelem;                            // increment number of elements in the shared buffer
             pt0.unlock ();                      // unlock
         }
    
         public int  consume ()
         {
             while ( nelem == 0 );               // while empty
             pt1.lock ();                        // lock
             int  ret;                           // variable to return
             ret = elem[c];                      // assignment
             c = (c + 1) % elem.length;          // new position in the circular array
             --nelem;                            // decrement number of elements in the shared buffer
             pt1.unlock ();                      // unlock
    
             return  ret;
         }
     }
    
     public static class  Producer extends Thread
     {
         private CircularBuffer  buf;
         private int     max;
    
         public  Producer (CircularBuffer  b, int  m)
         {
             buf = b;
             max = m;
         }
    
         public void  run ()
         {
             for ( int i = 0;  i < max;  ++i ) {
                 buf.produce (i);
             }
         }
     }
    
     public static class  Consumer extends Thread
     {
         private CircularBuffer  buf;
         private int     max;
    
         public  Consumer (CircularBuffer  b, int  m)
         {
             buf = b;
             max = m;
         }
    
         public void  run ()
         {
             int  data, previousData;
    
             data = buf.consume ();
             for ( int i = 0;  i < max - 1;  ++i ) {
                 System.out.printf (data + " ");
                 previousData = data;
                 data = buf.consume ();
                 if ( previousData > data )
                     throw new  RuntimeException ("Incorrect data order");
             }
             System.out.printf (data + " ");
         }
     }
    

    }

  • There is a single consumer that will display the elements deposited in the buffer.

    import  java.util.concurrent.atomic.AtomicBoolean;
    
    public class  ProducerConsumer
    {
        public static void  main (String[]  args)
        {
            if ( args.length != 1 ) {
                throw new  RuntimeException ("Usage: fileName number");
            }
            int         N     = 6;  // Size of circular buffer
            int         max   = Integer.parseInt (args[0]);  // number of elements to produce
            CircularBuffer  buf = new  CircularBuffer (N);
            Consumer    cons  = new  Consumer (buf, max);
            Producer    produ = new  Producer (buf, max);
    
            cons.start(); produ.start();
        }
    
        public static class  Peterson
        {
            private volatile int  turn;
            private AtomicBoolean[]  flag = new  AtomicBoolean[2];
            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[id].get() )
                    Thread.yield ();
            }
    
            public void  unlock ()
            {
                flag[id].set (false);
                turn = other ();
            }
        }
    
        public static class  CircularBuffer
        {
            private volatile int[]  elem;
            private volatile int    nelem;          // control elements in buffer
            private int  p;                         // consumer position
            private int  c;                         // producer position
            private Peterson  pt0 = new  Peterson (0);
            private Peterson  pt1 = new  Peterson (1);
    
            // Shared circular buffer
            public  CircularBuffer (int  N)
            {
                elem  = new  int[N];
                p     = 0;
                c     = 0;
                nelem = 0;
            }
    
            public void  produce (int  e)
            {
                while ( nelem == elem.length );     // while full
                pt0.lock ();                        // lock
                elem[p] = e;                        // produce new element
                p = (p + 1) % elem.length;          // new position in the circular array
                ++nelem;                            // increment number of elements in the shared buffer
                pt0.unlock ();                      // unlock
            }
    
            public int  consume ()
            {
                while ( nelem == 0 );               // while empty
                pt1.lock ();                        // lock
                int  ret;                           // variable to return
                ret = elem[c];                      // assignment
                c = (c + 1) % elem.length;          // new position in the circular array
                --nelem;                            // decrement number of elements in the shared buffer
                pt1.unlock ();                      // unlock
    
                return  ret;
            }
        }
    
        public static class  Producer extends Thread
        {
            private CircularBuffer  buf;
            private int     max;
    
            public  Producer (CircularBuffer  b, int  m)
            {
                buf = b;
                max = m;
            }
    
            public void  run ()
            {
                for ( int i = 0;  i  data )
                        throw new  RuntimeException ("Incorrect data order");
                }
                System.out.printf (data + " ");
            }
        }
    }
Source Link
user61445
user61445
Loading