You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Minecraft插件中实现每秒执行一次的while函数(禁用Thread.sleep())

嘿,这个坑我踩过好多次!Minecraft插件开发里绝对不能用Thread.sleep(),一用整个服务器都得卡成PPT。给你几个靠谱的替代方案,都是圈内常用的:

方案1:用 Bukkit/Paper 同步调度器(最常用)

Bukkit API 自带的调度器是处理这类定时任务的首选,它能在服务器主线程安全地按间隔重复执行逻辑,完全不会阻塞整个进程。核心是用runTaskTimer()替代while循环,它会帮你自动管理任务的重复执行,直到你主动取消。

举个实际代码例子:

// 先获取调度器实例
BukkitScheduler scheduler = Bukkit.getScheduler();

// 启动定时任务:延迟0秒立刻开始,每1秒(对应20个游戏tick,MC服务器每秒跑20 tick)执行一次
int taskId = scheduler.runTaskTimer(yourPluginInstance, new Runnable() {
    @Override
    public void run() {
        // 这里写你要每秒执行的核心逻辑
        // 比如给在线玩家发提示消息
        Bukkit.broadcastMessage("这是每秒执行一次的任务!");
    }
}, 0L, 20L);

// 要是后续需要停止任务(比如满足某个条件时),调用这个就行
// scheduler.cancelTask(taskId);

⚠️ 注意:这个是同步任务,所以里面的逻辑不能太耗时(比如复杂计算、IO操作),不然还是会拖慢服务器。如果有耗时操作,看下面的异步方案。

方案2:异步调度器(处理耗时逻辑)

如果你的每秒逻辑里有数据库查询、网络请求这类费时间的操作,必须用异步任务,避免卡住主线程。用runTaskTimerAsynchronously()方法就行:

int asyncTaskId = scheduler.runTaskTimerAsynchronously(yourPluginInstance, new Runnable() {
    @Override
    public void run() {
        // 这里放耗时的异步逻辑,比如查数据库
        String data = someDatabase.query("SELECT ...");
        
        // 重点:异步线程里不能直接操作游戏内的实体、方块!
        // 要是需要修改游戏内容,得切回主线程:
        scheduler.runTask(yourPluginInstance, () -> {
            // 在这里安全操作游戏对象,比如给玩家背包加物品
            Player player = Bukkit.getPlayer("PlayerName");
            if (player != null) {
                player.sendMessage("从数据库拿到的数据:" + data);
            }
        });
    }
}, 0L, 20L);
方案3:BukkitRunnable 封装写法(更简洁)

Bukkit还提供了BukkitRunnable类,写法更清爽,本质和调度器是同一个东西,适合需要在任务里判断停止条件的场景:

new BukkitRunnable() {
    @Override
    public void run() {
        // 你的每秒执行逻辑
        if (someStopCondition) { // 比如某个玩家下线了,或者任务完成了
            this.cancel(); // 满足条件就停止任务
        }
    }
}.runTaskTimer(yourPluginInstance, 0L, 20L);
几个关键提醒
  • 任务不用了一定要取消,不然插件卸载后任务还会继续跑,导致内存泄漏。
  • 永远记住MC服务器的tick是20/秒,所以间隔参数填20就是1秒,别搞成1了!
  • 异步线程绝对不能直接操作游戏内对象,必须通过scheduler.runTask()切回主线程操作。

内容的提问来源于stack exchange,提问作者Tomáš Soušek

火山引擎 最新活动