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

Java线程wait与布尔值监控:厨房烤箱多线程实现疑问

解决多线程厨房模拟中烤箱烘烤状态的线程安全问题

这个场景太典型了——我之前做过一个餐厅后厨模拟的项目,也碰到过几乎一模一样的问题!核心痛点就是要确保烤箱的烘烤周期是要么完整跑完X时长且全程开启,要么中途被关闭就立刻返回失败,而普通布尔值在多线程下的可见性和原子性问题刚好踩中了这个坑。下面给你两个实用的解决方案,根据你的项目复杂度选就行:

方案一:用原子类实现轻量级状态检查

把标记烤箱状态的普通boolean换成AtomicBoolean,它能保证状态的读写都是线程安全的,同时我们可以用循环等待+实时检查的方式,确保中途状态变化能立刻被感知:

import java.util.concurrent.atomic.AtomicBoolean;

public class Oven {
    private final AtomicBoolean isOvenOn = new AtomicBoolean(true);

    public boolean bakeDish(long bakeTimeMs) {
        // 先确认烤箱当前是开启的,才启动烘烤
        if (!isOvenOn.get()) {
            return false;
        }

        long startTime = System.currentTimeMillis();
        try {
            // 循环等待,每次间隔100ms检查一次状态,避免忙等
            while (System.currentTimeMillis() - startTime < bakeTimeMs) {
                Thread.sleep(100);
                // 中途发现烤箱关闭,直接返回未熟透
                if (!isOvenOn.get()) {
                    return false;
                }
            }
            // 最后再确认一次状态,防止最后一刻被关闭
            return isOvenOn.get();
        } catch (InterruptedException e) {
            // 线程被中断时,保留中断状态并返回失败
            Thread.currentThread().interrupt();
            return false;
        }
    }

    // 关闭烤箱的方法,线程安全
    public void turnOffOven() {
        isOvenOn.set(false);
    }
}

这个方案的优点是实现简单,不需要复杂的锁机制,适合状态变更不频繁的场景。

方案二:用锁+条件变量实现精准同步

如果你的项目需要更高效的状态响应(比如烤箱关闭时立刻唤醒烘烤线程,不需要等待sleep结束),可以用ReentrantLock配合Condition来实现,所有状态操作都在锁的保护下,完全避免并发问题:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Oven {
    private final ReentrantLock ovenLock = new ReentrantLock();
    private final Condition ovenTurnedOff = ovenLock.newCondition();
    private boolean isOvenOn = true;

    public boolean bakeDish(long bakeTimeMs) {
        ovenLock.lock();
        try {
            if (!isOvenOn) {
                return false;
            }
            // 等待指定时长,或者直到烤箱被关闭的信号唤醒
            boolean interruptedByShutdown = ovenTurnedOff.await(bakeTimeMs, TimeUnit.MILLISECONDS);
            // 如果返回true,说明是被关闭信号唤醒的,返回未熟透;否则是等待超时,再确认状态
            return !interruptedByShutdown && isOvenOn;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        } finally {
            ovenLock.unlock();
        }
    }

    public void turnOffOven() {
        ovenLock.lock();
        try {
            isOvenOn = false;
            ovenTurnedOff.signalAll(); // 唤醒所有正在烘烤的线程
        } finally {
            ovenLock.unlock();
        }
    }
}

这个方案的优势是响应更及时,而且状态的一致性得到了绝对保障,适合并发场景复杂、状态变更频繁的项目。

避坑提醒

  • 绝对不要用普通boolean存状态:多线程下非原子的读写会导致可见性问题——比如烤箱已经关闭,但烘烤线程还读取到旧的true值,返回错误的“熟透”结果。
  • 别直接用Thread.sleep(bakeTimeMs)后再检查状态:这段时间内状态被修改的话,线程无法及时响应,只能等到sleep结束才发现,完全不符合需求。
  • 处理InterruptedException时一定要重置中断状态:避免上层逻辑丢失中断信号,导致后续线程行为异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:19:46