Как я могу решить проблему с потребителем? - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь реализовать программу со складом, потребителем и производителем, используя ReentrantLock. У меня есть очередь cycli c, основанная на массиве как хранилище товаров. Производитель может производить продукт до n раз. Я столкнулся с проблемой, что потребитель не вовлечен в процесс. Подскажите, где я ошибся?

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]+" ");
    }
  }
}

Класс производителя

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){}
        }
    }
   }

Класс потребителя

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();
      }
    }
  }

Основной класс

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);
 }

}

1 Ответ

0 голосов
/ 03 мая 2020

Во-первых, в своем основном классе вы забыли инициировать поток потребителя, вызвав для него команду start.

new Thread(consumer).start();

Во-вторых, я думаю, что у вас также есть проблема с logi c, когда вы не меняете хвост положил. Я не уверен, было ли это преднамеренным, но вышеуказанное изменение должно решить вашу проблему.

...