0

I'm trying to implement a program with a warehouse, consumer, and manufacturer using ReentrantLock. I have a cyclic queue based on an array as a storage of goods. The Producer can produce the product up to n times. I faced the problem that the consumer is not involved in the process. Can you tell me where I made a mistake?

package com.company;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

public class Storage {
private final int q[];
private int head,tail,switcher;
ReentrantLock lock= new ReentrantLock();;
Condition notfull = lock.newCondition();
Condition notempty = lock.newCondition();

public Storage(int size) {
    q = new int[size];
    head = 0;
    tail = 0;
}

public boolean isFull(){
    return ((tail == q.length-2)&&(head==0))||(tail+1==head);
}

public boolean isEmpty(){ 
    return ((tail==q.length-1)&&(head==0))||(head+1==tail)||(head+1==0);
}

public int put(int el){ 
    lock.lock();
    try {
        while (isFull()){
            notfull.await();
        }
        q[tail]=el;
        System.out.print("PRODUCER ADDED: "+el);
        System.out.print("STATUS OF STORAGE: ");
        print();
        System.out.println();
        System.out.println("head = "+head);
        System.out.println("tail = "+tail);
        notempty.signalAll();
    }
    catch (InterruptedException e){}
    finally {
        lock.unlock();
        return el;
    }
}

public int get(){
    lock.lock();
    try {
        while (isEmpty()) notempty.await();
        head = step(head);
        System.out.print("CONSUMER GOT: "+q[head]);
        System.out.print("STATUS OF STORAGE: ");
        print();
        System.out.println();
        System.out.println("head = "+head);
        System.out.println("tail = "+tail);
        notfull.signalAll();
    }
    catch (InterruptedException e){}
    finally {
        lock.unlock();
        return q[head];
    }

}

public int step(int i){
    int s;
    s=(i+1)%q.length;
    return s;
}

public void print() {
    int i;
    for (i = head; i != tail; i = step(i)) {
        System.out.print(q[i]+" ");
    }
  }
}

Producer class

public class Producer implements Runnable {
protected int n =10; // limit of producing
private int el=1; //
private Storage q;
Thread p;

public Producer(Storage q){
    this.q = q;
    p=new Thread(this, "Producer");
}


public void run() {
    for (int i=1;i<n;i++){
        q.put(el++);
        try {
            p.sleep(2000);
        }
        catch (InterruptedException e){}
        }
    }
   }

Consumer class

public class Consumer implements Runnable {
private Storage q;
static Thread c;

public Consumer(Storage q){
    this.q = q;
    c=new Thread(this, "Producer");
}

@Override
public void run(){
      for (int i=1; i<10;i++){
          try {
              c.sleep(1000);
          } catch (InterruptedException e){}
          q.get();
      }
    }
  }

main class

public class Main {
public static void main(String[] args) {
    Storage q = new Storage(6); // общий склад
    Producer producer = new Producer(q);
    Consumer consumer = new Consumer(q);
    new Thread(producer).start();
    new Thread(consumer);
 }

}

Liza
  • 1

1 Answers1

0

Firstly in your main class you forgot initiate the Consumer thread by calling start on it.

new Thread(consumer).start();

Secondly I think you have a logic issue as well where you are not changing your tail on put. I am not sure if it was intentional but the above change should solve your problem.

naivecoder
  • 106
  • 4