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

Java实现Minecraft Bukkit/Spigot插件每5秒重复执行任务

Bukkit/Spigot插件实现5秒重复任务方案

嘿,我来帮你搞定这个每5秒重复执行的任务!在Bukkit/Spigot插件开发里,最稳妥的方式是用官方提供的Bukkit调度器API,比Java原生的Timer更适配服务器环境,不会出现线程安全或者插件卸载后任务还乱跑的问题,咱直接上代码:

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;

public class YourPlugin extends JavaPlugin {
    // 保存任务实例,方便插件禁用时取消,避免内存泄漏
    private BukkitTask repeatTask;

    @Override
    public void onEnable() {
        getLogger().info("TBC Enabled");

        // 创建每5秒重复执行的任务
        repeatTask = Bukkit.getScheduler().runTaskTimer(this, () -> {
            // ~~ 从此处到下一个注释的代码需要每5秒执行一次
            for (org.bukkit.entity.Player player : Bukkit.getOnlinePlayers()) {
                player.sendMessage("N/A");
            }
            // ~~ 结束需要重复执行的代码块
        }, 0L, 100L); 
        // 参数说明:
        // 0L = 任务启动后立即执行第一次(延迟0秒)
        // 100L = 每100tick重复一次(Minecraft每秒跑20tick,100tick就是5秒)
    }

    @Override
    public void onDisable() {
        // 插件禁用时务必取消任务,防止任务继续占用资源
        if (repeatTask != null && !repeatTask.isCancelled()) {
            repeatTask.cancel();
        }
        getLogger().info("TBC Disabled");
    }
}

关键知识点说明

  • Bukkit调度器的优势:默认在服务器主线程执行任务,操作玩家、方块等Bukkit API时不会触发线程安全问题,而且任务会和插件生命周期绑定,管理起来更省心。
  • tick的计算:Minecraft服务器每秒固定运行20个游戏tick,所以5秒就是 20 * 5 = 100 tick,这是Bukkit任务周期的标准单位。
  • 任务取消的必要性:如果不保存任务实例并在onDisable中取消,插件卸载后任务可能还在后台运行,导致服务器报错或者内存泄漏。

关于Java原生Timer的备选方案(不推荐)

如果你非要用Java原生的Timer实现,一定要注意:Timer的线程是独立于Bukkit主线程的,直接操作Bukkit API会报错,必须把业务逻辑切换到主线程执行,代码示例如下:

import java.util.Timer;
import java.util.TimerTask;

@Override
public void onEnable() {
    getLogger().info("TBC Enabled");

    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // 必须用Bukkit调度器把操作切回主线程!
            Bukkit.getScheduler().runTask(YourPlugin.this, () -> {
                for (org.bukkit.entity.Player player : Bukkit.getOnlinePlayers()) {
                    player.sendMessage("N/A");
                }
            });
        }
    }, 0, 5000); // 0毫秒延迟,每5000毫秒(5秒)执行一次
}

这种方式不仅代码更繁琐,还需要自己手动管理Timer的取消(比如在onDisable中调用timer.cancel()),所以还是优先用Bukkit官方的调度器方案哦!

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

火山引擎 最新活动