生产者死锁 - 消费者线程

Deadlock in Producer - consumer thread

我遇到了 "producer - consumer task" 中可能出现的死锁问题。 一切都应该按以下方式工作:

  1. 生产者应生成 int[] 数组并将其添加到集合中
  2. 消费者应该获取这些数组,将它们放入第二个集合并在输出中打印

在调试模式下,我注意到一段时间后两个任务都在 this.wait(); 方法上暂停。

你能帮我解释一下这段代码有什么问题吗? :)
谢谢!

生产者任务class

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

消费者任务class

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,这同样适用于消费者线程。

记住两者是两个不同的实例,都成功​​获得了对单个对象的锁定,然后都进入了等待状态。