簡體   English   中英

生產者中的死鎖-使用者線程

[英]Deadlock in Producer - consumer thread

我對“生產者-消費者任務”中的可能死鎖存在問題。 一切都應以以下方式工作:

  1. 生產者應該生成int []數組並將其添加到集合中
  2. 消費者應將這些數組放入第二個集合並在輸出中打印

在調試模式下,我注意到一段時間后,這兩個任務都被掛在了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();
}
}

您需要一個用於線程間通信的公共對象。

現在,您this對象用作鎖定對象,並在生產者線程中通知bufferLock,並且對消費者線程也是如此。

請記住,這兩個實例是兩個不同的實例,並且都成功獲得了對單個對象的鎖定,然后都進入了等待狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM