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

Java线程中判定条件成立但返回的boolean值仍为false问题求助

问题原因及解决方案

核心问题1:异步执行时序错误

run()方法中启动的是独立子线程,你调用run()之后立刻调用owner()方法取值时,子线程的遍历判断逻辑还没执行到赋值isOwner = true的步骤,拿到的自然是布尔值默认初始值false。

核心问题2:线程变量可见性问题

你定义的public boolean isOwner;没有加volatile修饰,Java内存模型下子线程对该变量的修改不会即时同步到主线程的工作内存,就算子线程已经赋值为true,主线程读取到的也可能是缓存的旧值false。

隐藏逻辑问题

你匹配到符合条件的方块后没有跳出循环,后续遍历到其他方块时,如果触发对应else分支会把已经设置为true的isOwner再次覆盖为false。

修复方案

方案1(保留异步逻辑)

通过CountDownLatch实现主线程等待子线程执行完成再取值,同时添加volatile修饰变量保证可见性,匹配成功后直接跳出循环避免值被覆盖,修改后代码如下:

public class IsOwner {

    private PlayerOwnedBlocks main;
    private Config config;
    private Location location;

    // 加volatile保证多线程变量可见性
    public volatile boolean isOwner;

    private Player player;
    // 用于等待子线程执行完成
    private CountDownLatch countDownLatch;

    public IsOwner(PlayerOwnedBlocks main) {
        this.main = main;
        this.config = new Config(this.main);
    }


    public void run(Player player, Location location) {
        countDownLatch = new CountDownLatch(1);
        // 初始化默认值避免历史值干扰
        isOwner = false;
        new Thread(() -> {
            try {
                for (OfflinePlayer p : Bukkit.getOfflinePlayers()) {
                    this.config.setup(p.getUniqueId());
                    ConfigurationSection getBlocks = this.config.getConfiguration().getConfigurationSection(".blocks");

                    if (getBlocks != null) {
                        for (String block : getBlocks.getKeys(false)) {
                            double x = getBlocks.getDouble(block + ".x");
                            double y = getBlocks.getDouble(block + ".y");
                            double z = getBlocks.getDouble(block + ".z");
                            List<String> owner = this.config.getConfiguration().getStringList(".owners");

                            if (location.getBlockX() == x && location.getBlockY() == y && location.getBlockZ() == z) {
                                if (owner.contains(player.getDisplayName())) {
                                    player.sendMessage("test1");
                                    isOwner = true;
                                    // 匹配成功直接结束子线程,避免后续逻辑覆盖值
                                    return;
                                } else {
                                    player.sendMessage("test2");
                                }
                            }
                        }
                    }
                }
            } finally {
                // 标记子线程执行完成
                countDownLatch.countDown();
            }
        }).start();
    }

    public boolean owner () {
        // 阻塞等待子线程执行完成再返回结果
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return this.isOwner;
    }
}

方案2(简化实现)

如果你的业务数据量不大,直接去掉子线程逻辑同步执行,不需要处理多线程同步问题,是最稳妥的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:06:02