我试图使重复runnable只持续一定次数,但是一旦整数达到一定数量,我找不到取消重复runnable的方法。
Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable() {
public void run() {
Random rand = new Random();
int rnum = rand.nextInt(main.allowed.size()) + 1;
e.getPlayer().getInventory().addItem(main.allowed.get(rnum));
for(int i = 0; i >= main.getConfig().getInt("SpawnerCase.HowManySpawners"); i++) {
// Something here.
}
}
}, 0L, 0L);
编辑: 我只需要知道如何从for语句中停止runnable。我从那个链接得到了这个想法(How to stop a Runnable scheduled for repeated execution after a certain number of executions)
请告诉我,如果我错了,但我认为你不想取消for循环中的runnable。那将在那时停止执行,但我认为它不会阻止它一次又一次地执行,因为它是无限期安排的。所以我的方法是取消计划,而不是在循环中终止它。
通过这种方法,我认为你可以做这样的事情,即使它有点棘手:
//We use atomicInteger because the Runnable will be in other thread
AtomicInteger currentIteration = new AtomicInteger(0);
int maxAttempts = 100;
Map<String, Integer> idToProcessIdMap = new HashMap<>();
final String customProcessId = UUID.randomUUID().toString();
Consumer<String> endProcessConsumer = ((generatedId) -> {
int processId = idToProcessIdMap.get(generatedId);
Bukkit.getScheduler().cancelTask(processId);
});
int taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable() {
public void run() {
Random rand = new Random();
int rnum = rand.nextInt(main.allowed.size()) + 1;
e.getPlayer().getInventory().addItem(main.allowed.get(rnum));
for(int i = 0; i >= main.getConfig().getInt("SpawnerCase.HowManySpawners"); i++) {
// Something here.
}
int currentIt = currentIteration.incrementAndGet();
if(currentIt > maxAttempts){
endProcessConsumer.accept(customProcessId);
}
}
}, 0L, 0L);
idToProcessIdMap.put(customProcessId, taskId);
编辑:简化版
AtomicInteger currentIteration = new AtomicInteger(0);
int maxAttempts = 100;
AtomicInteger processId = new AtomicInteger();
int taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(main, new Runnable() {
public void run() {
Random rand = new Random();
int rnum = rand.nextInt(main.allowed.size()) + 1;
e.getPlayer().getInventory().addItem(main.allowed.get(rnum));
for(int i = 0; i >= main.getConfig().getInt("SpawnerCase.HowManySpawners"); i++) {
// Something here.
}
int currentIt = currentIteration.incrementAndGet();
if(currentIt > maxAttempts){
Bukkit.getScheduler().cancelTask(processId.get());
}
}
}, 0L, 0L);
processId.set(taskId);
我在代码中做的是首先创建一个变量来识别我们在哪个迭代中。然后,我为您正在运行的进程创建自定义标识符,并将其与HashMap中的实际进程ID相关联。我们需要这样做,因为当我们运行这个过程时,我们仍然不知道它的id是什么,因此我们无法直接阻止它
此外,我创建了一个消费者,当我们达到最大执行时间时,我可以在流程中调用这个消费者来自行安排。