取消Runnable(Java)

问题描述 投票:0回答:1

我试图使重复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

java
1个回答
0
投票

请告诉我,如果我错了,但我认为你不想取消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是什么,因此我们无法直接阻止它

此外,我创建了一个消费者,当我们达到最大执行时间时,我可以在流程中调用这个消费者来自行安排。

© www.soinside.com 2019 - 2024. All rights reserved.