You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java线程公平策略如何工作?锁实现生产者消费者异常问题咨询

生产者-消费者锁实现的问题分析与修正

首先要指出你贴的代码里有两个致命错误:

  1. Condition的await()调用必须在持有锁的状态下执行,你现在在lock.lock()之前就调用pCondition.await()和cCondition.await(),这会直接抛出IllegalMonitorStateException,所谓“开启公平策略能运行”大概率是巧合或者你实际运行的代码和贴出的不一致。
  2. 消费者方法里没有对number做减一操作,消费后数量不变,逻辑完全错误。

回到你的疑问:不是必须依赖公平锁或await才能实现“生产1个立即消费”的逻辑,但必须用正确的等待唤醒机制,公平锁只是可选优化项。

核心逻辑说明

公平锁的作用是让线程按等待顺序获取锁,避免饥饿,但它不是实现交替生产消费的必要条件。而await()/signal()是Condition的核心机制,用来精准唤醒指定类型的线程,这是实现生产者消费者等待唤醒的标准方式——如果不用这类等待唤醒机制,线程只能不断轮询判断条件,不仅浪费CPU,还无法保证严格的交替执行(因为线程调度是操作系统决定的,非公平锁下可能会出现同一个线程重复获取锁的情况)。

修正后的正确代码(非公平锁也能正常运行)

public class ProductLockDemo2 {
    private Integer number = 0;
    // 使用非公平锁,性能更高
    private Lock lock = new ReentrantLock(false);
    private Condition pCondition = lock.newCondition();
    private Condition cCondition = lock.newCondition();

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public void produce() throws InterruptedException {
        lock.lock();
        try {
            // 用while循环防止虚假唤醒(单个if可能被异常唤醒导致逻辑错误)
            while (getNumber() >= 10) {
                pCondition.await();
            }
            number++;
            System.out.println("producing number :" + number);
            Thread.sleep(1000);
            // 唤醒等待的消费者线程
            cCondition.signal();
        } finally {
            lock.unlock();
        }
    }

    public void consume() throws InterruptedException {
        lock.lock();
        try {
            while (getNumber() <= 0) {
                cCondition.await();
            }
            System.out.println("consuming:" + number);
            Thread.sleep(1000);
            number--; // 补充消费后的数量递减
            // 唤醒等待的生产者线程
            pCondition.signal();
        } finally {
            lock.unlock();
        }
    }
}

修正要点

  • 所有同步逻辑必须放在lock.lock()和lock.unlock()之间,确保操作的原子性
  • 用while循环判断条件,避免虚假唤醒(JVM允许线程在没有被signal的情况下唤醒)
  • 消费者方法补充number--,修正逻辑错误
  • 即使使用非公平锁,只要等待唤醒逻辑正确,依然能严格实现“生产一个、消费一个”的交替执行逻辑

内容的提问来源于stack exchange,提问作者keepmoving

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:35:22