取消可运行(Java)

时间:2018-08-29 15:30:49

标签: java

我试图使重复的可运行对象仅持续一定的次数,但是我找不到找到一种方法,一旦整数达到某个数字,就可以取消重复的可运行对象。

                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语句内部停止可运行对象。我从那个链接(How to stop a Runnable scheduled for repeated execution after a certain number of executions)那里得到了这个主意

1 个答案:

答案 0 :(得分:0)

如果我错了,请告诉我,但我认为您不想取消for循环中的可运行对象。 那会在那个时候停止执行,但是我认为它不会阻止它一次又一次地执行,因为它是无限期地调度的。因此,我的方法是取消调度,而不是在循环内终止它。

通过这种方法,我认为您可以执行以下操作,即使有些棘手:

//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,因此我们将无法直接停止它

此外,我创建了一个使用者,可以在达到最大执行时间时在流程内调用该使用者,以取消计划本身。