首先,这是 Minecraft/Bukkit 相关的,但我相信我的问题不是 Bukkit 特有的,只是忽略了我认为(我希望)的一些小事情。
我的代码的最底部是一个randomDelay
和randomPeriod
。 run()
函数根据这两个变量以给定的时间间隔重复运行。我不知道如何在可运行程序启动后动态更改这些。我想让可运行的每个周期的长度不同,但问题是,一旦 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/