gpt4 book ai didi

java - 如何动态改变重复Java Runnable的周期?

转载 作者:行者123 更新时间:2023-12-01 18:26:51 27 4
gpt4 key购买 nike

首先,这是 Minecraft/Bukkit 相关的,但我相信我的问题不是 Bukkit 特有的,只是忽略了我认为(我希望)的一些小事情。

我的代码的最底部是一个randomDelayrandomPeriodrun() 函数根据这两个变量以给定的时间间隔重复运行。我不知道如何在可运行程序启动后动态更改这些。我想让可运行的每个周期的长度不同,但问题是,一旦 run() 函数开始,它似乎使用分配的第一个值。

package code.malon;

import java.util.Random;

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

public final class RandomResponse extends JavaPlugin {

Random rand = new Random();
int min = 20;
int max = 200;
long randomDelay = rand.nextInt((max - min) + 1) + min;
long randomPeriod = rand.nextInt((max - min) + 1) + min;

public void onEnable() {

BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
scheduler.scheduleSyncRepeatingTask(this, new Runnable() {

@Override
public void run() {
randomDelay = rand.nextInt((max - min) + 1) + min;
randomPeriod = rand.nextInt((max - min) + 1) + min;
}
}, randomDelay, randomPeriod);
}
}

最佳答案

让我们递归一下!噢耶!

您的代码不是动态的,因为您在 Bukkit 的 PluginClassLoader 构造 RandomResponse初始化字段。这将创建一个new Random(),生成一次随机值并安排其延迟“randomDelay”。那不是动态的。让我们用一个小技巧来解决这个问题:

public final class RandomResponse extends JavaPlugin {

final Random rand = new Random();
final int min = 20;
final int max = 200;
// I made these final for arbitrary reasons.

private RandomResponse randomResponse;

@Override
public void onEnable() {
randomResponse = this; // To use in anonymous class.

// The delay should be random, so we compute it within onEnable() method.
// We do not leave it in the class because then it's initialized by constructing.
long randomDelay = rand.nextInt((max - min) + 1) + min;

getServer().getScheduler().runTaskLater(this, new Runnable() {

@Override
public void run() {
/*
* Stuff to do
*/
// Call itself again some time later.
long randomDelay = rand.nextInt((max - min) + 1) + min;
getServer().getScheduler().runTaskLater(randomResponse, this, randomDelay);
}

}, randomDelay);
}
}

请注意,scheduleSyncRepeatingTask 在任务开始运行后无法更改其周期长度。因此,您必须递归调用。要允许取消并重新运行任务,请使用以下命令:

BukkitTask task;

void runTask() {
cancelTask();
task = getServer().getScheduler().runTaskLater(this, new Runnable() {

@Override
public void run() {
/*
* Stuff to do
*/
// Call itself again some time later.
long randomDelay = rand.nextInt((max - min) + 1) + min;
task = getServer().getScheduler().runTaskLater(randomResponse, this, randomDelay);
}

}, randomDelay);
}

void cancelTask() {
if (task != null) try {
task.cancel();
} catch(Throwable ex) {
// Ignore.
}
}

作为您可能没有想到的旁注,您可能需要使用 BukkitRunnable而不是 java.lang 中的 Runnable 类。

关于java - 如何动态改变重复Java Runnable的周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25837873/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com