有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java等待在while循环内/外同步

我正在研究消费者/生产者的问题,以了解Java中的并发性问题。我的问题可能与C/P问题本身相邻。在下面的代码片段中,如果我使用版本1,程序似乎运行良好,而使用版本2,我似乎在一段时间后出现死锁

我只发布生产者类,因为不需要消费者类

  • 缓冲区是生产者存放产出的地方
  • 我只是把1的整数加进去
  • 而(正确)是保持线程持续运行

我的问题是:我知道在Java API中调用wait()的结构是:synchronized->;而->;等待但在这种情况下会发生什么:while->;同步->;等待如果在wait()期间,使用者调用notifyAll(),生产者再次醒来,那么代码不会从调用wait()的地方继续,最终会到达while(buffer.remainingCapacity()==0)

我已经四处挖掘,看看是否有人问过这个问题,但找不到任何具体的问题

第1版

public class Producer extends Thread {
    ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(10);
    public Producer(ArrayBlockingQueue<Integer> buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        while (true) {
            synchronized(buffer) {
                while (buffer.remainingCapacity() == 0) {
                    try {
                        buffer.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            try {
                synchronized (buffer) {
                    buffer.add(1);
                    System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
                    buffer.notifyAll();
                }
            } catch (IllegalStateException ex) {
                ex.printStackTrace();
            }
        }
    }
}

第2版

public class Producer extends Thread {
    ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(10);

    public Producer(ArrayBlockingQueue<Integer> buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        while (true) {
            while (buffer.remainingCapacity() == 0) {
                synchronized (buffer) {
                    try {
                        buffer.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            try {
                synchronized (buffer) {
                    buffer.add(1);
                    System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
                    buffer.notifyAll();
                }
            } catch (IllegalStateException ex) {
                ex.printStackTrace();
            }
        }
    }
}

就为了它,这是另一个版本代码的问题,似乎是工作。我只是把它放在这里,以防它对其他人有帮助,或者如果有人能告诉我它是否错,为什么错。与上面的版本相比,这个版本的wait和notifyAll方法在代码中的位置发生了“翻转”

while(true) {
            while(buffer.remainingCapacity() == 0){
                synchronized (buffer){
                    buffer.notifyAll();
                }
            }
            try {
                buffer.add(1);
                System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
            } catch (IllegalStateException ex) {
                synchronized (buffer){
                    try {
                        buffer.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

共 (0) 个答案