2015-11-15 3 views
0

У меня есть проблема с возможным тупиком в «задаче производителя - потребителя». Все должно работать в следующим образом:Тупик в Продюссе - потребительская нить

  1. Производитель должен создавать и добавлять ИНТ [] массивы в коллекции
  2. Потребитель должен принять эти массивы, положить их на второй сбор и печать на выходе

В режиме debbug я заметил, что через некоторое время оба taks приостановлены на this.wait(); способ.

Не могли бы вы помочь мне и объяснить, что не так с этим кодом? :)
Спасибо!

Производитель Задача класс

public class ProducerTask extends Thread{ 

private static final Object bufforLock = new Object(); 
private static LinkedList<Integer[]> buffor; 

public ProducerTask(){ 
    if(buffor == null) 
     buffor = new LinkedList<>(); 
    this.setName("@ProducerTask"); 
} 

@Override 
public void run() { 
    synchronized (this) { 
     try { 
      for (int i = 0; i < 100; i++) { 
       while (isBufforFull()) { 
        System.err.println("ProducerTask is waiting"); 
        this.wait(); 
       } 
       Integer[] randomIntArray = getRandomIntArray(); 

       addToBuffor(randomIntArray); 
      } 
     } 
     catch (InterruptedException ex) { 
     } 
    } 
} 

public static void removeLast(){ 
    synchronized(bufforLock){ 
     buffor.removeLast(); 
     bufforLock.notifyAll(); 
    } 
} 

public static Integer[] getLast(){ 
    synchronized(bufforLock){ 
     return buffor.getLast(); 
    } 
} 

public static boolean isBufforFull(){ 
    synchronized(bufforLock){ 
     return buffor.size() == 10; 
    } 
} 

public static boolean isBufforEmpty(){ 
    synchronized(bufforLock){ 
     return buffor.isEmpty(); 
    } 
} 

public static void addToBuffor(Integer[] array){ 
    synchronized(bufforLock){ 
     buffor.addFirst(array); 
     bufforLock.notifyAll(); 
    } 
} 

public static LinkedList<Integer[]> getBuffor(){ 
    synchronized(bufforLock){ 
     return buffor; 
    } 
} 

private Integer[] getRandomIntArray(){ 
    int maxSize = 10; 
    Integer[] array = new Integer[maxSize]; 
    for(int i = 0 ; i < maxSize ; i++){ 
     int value = (int) (Math.random() * 100); 
     array[i] = Integer.valueOf(value); 
    } 
    return array; 
} 
} 

Потребительской задача класс

public class ConsumerTask extends Thread { 

private static LinkedList<Integer[]> buffor; 

public ConsumerTask() { 
    if (buffor == null) { 
     buffor = new LinkedList<>(); 
    } 
    this.setName("@ConsumerTask"); 
} 

@Override 
public void run() { 
    synchronized (this) { 
     try { 
      while (true) { 
       while (ProducerTask.isBufforEmpty()) { 
        System.err.println("ConsumerTask is waiting"); 
        this.wait(); 
       } 

       Integer[] array = ProducerTask.getLast(); 
       this.arraySortByInserting(array); 
       this.buffor.addFirst(array); 
       ProducerTask.removeLast(); 
      } 
     } 
     catch (InterruptedException ex) {} 
    } 
} 

private Integer[] arraySortByInserting(Integer[] aArrayToSort) { 

    if(aArrayToSort == null || aArrayToSort.length == 0) 
     return null; 

    this.printArray(aArrayToSort, "Array before sorting"); 

    for (int i = 1; i < aArrayToSort.length; i++) { 
     int intValue = aArrayToSort[i]; 
     int j = i; 
     while ((j > 0) && (aArrayToSort[j - 1] > intValue)) { 
      aArrayToSort[j] = aArrayToSort[j - 1]; 
      j--; 
     } 
     aArrayToSort[j] = intValue; 
    } 


    this.printArray(aArrayToSort, "Array after sorting"); 

    return aArrayToSort; 
} 

private void printArray(Integer[] aArray, String aMessage) { 

    System.out.print(aMessage + " ["); 

    for (int intElement : aArray) { 
     System.out.print(intElement + " "); 
    } 

    System.out.print("]"); 
    System.out.println(); 
} 
} 
+0

См. Https://docs.oracle.com/javase/tutorial/essential/concurrency/liveness.html –

ответ

4

Вам нужен общий объект, который будет использоваться для связи среди потоков.

Прямо сейчас вы используете this как объект, на котором вы получаете блокировку, и вы уведомляете о bufferLock в потоке производителя, и то же самое относится к потребительской цепочке.

Помните, что оба являются двумя разными экземплярами, и оба успешно получают блокировку для отдельных объектов, а затем оба входят в состояние ожидания.

+0

Отличный anwser, теперь мне все кажется ясным, спасибо! :) – Wicia

Смежные вопросы