生产者死锁 - 消费者线程

时间:2015-11-15 16:01:20

标签: java multithreading synchronization task deadlock

我在"生产者 - 消费者任务"中可能出现死锁问题。 一切都应该按照以下方式运作:

  1. 生产者应生成并将int []数组添加到集合
  2. 消费者应该接受这些数组,将它们放到第二个集合中并在输出中打印
  3. 在debbug模式中,我注意到一段时间后两个tak都暂停在 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();
    }
    }
    

1 个答案:

答案 0 :(得分:4)

您需要一个用于线程间通信的公共对象。

现在您使用this作为锁定对象,并在生产者线程中通知bufferLock,同样适用于消费者线程。

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