jack_a1SCS
  1.   BukkitTask aa= Bukkit.getScheduler().runTaskTimerAsynchronously(ZhiWumian.plugin,()->{
  2.             Savezhiwudate.save();
  3.         },0,ZhiWumian.plugin.getConfig().getLong("savetime")*20*60); 这种异步算分支线程还是主线程啊
复制代码


3TUSK
Asynchronous tasks should never access any API in Bukkit. Great care should be taken to assure the thread-safety of asynchronous tasks.
Returns a task that will repeatedly run asynchronously until cancelled, starting after the specified number of server ticks.

——https://hub.spigotmc.org/javadoc ... TimerAsynchronously(org.bukkit.plugin.Plugin,java.lang.Runnable,long,long)


Javadoc 并没有说明是异步单线程还是异步多线程,但就「不要访问 Bukkit API」这个说法来看,应该是异步多线程。

吕易天
本帖最后由 吕易天 于 2021-6-19 10:07 编辑

Async任务不是在主线程执行的
org.bukkit.craftbukkit.xxx.scheduler.CraftScheduler.java:
  1.     @Override
  2.     public BukkitTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
  3.         CraftScheduler.validate(plugin, runnable);
  4.         if (delay < 0L) {
  5.             delay = 0L;
  6.         }
  7.         if (period == 0L) {
  8.             period = 1L;
  9.         } else if (period < -1L) {
  10.             period = -1L;
  11.         }
  12.         return this.handle(new CraftAsyncTask(this.asyncScheduler.runners, plugin, runnable, this.nextId(), period), delay);
  13.     }
  14.     protected CraftTask handle(CraftTask task, long delay) {
  15.         if (!this.isAsyncScheduler && !task.isSync()) {
  16.             this.asyncScheduler.handle(task, delay);
  17.             return task;
  18.         }
  19.         task.setNextRun((long)this.currentTick + delay);
  20.         this.addTask(task);
  21.         return task;
  22.     }
  23.     protected void addTask(CraftTask task) {
  24.         AtomicReference<CraftTask> tail = this.tail;
  25.         CraftTask tailTask = tail.get();
  26.         while (!tail.compareAndSet(tailTask, task)) {
  27.             tailTask = tail.get();
  28.         }
  29.         tailTask.setNext(task);
  30.     }
复制代码

org.bukkit.craftbukkit.xxx.scheduler.CraftAsyncScheduler.java:
  1. private final ThreadPoolExecutor executor = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 30L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build());
  2.     private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Craft Async Scheduler Management Thread").build());
  3.     private final List<CraftTask> temp = new ArrayList<CraftTask>();

  4. @Override
  5.     public void mainThreadHeartbeat(int currentTick) {
  6.         this.currentTick = currentTick;
  7.         this.management.execute(() -> this.runTasks(currentTick));
  8.     }

  9.     private synchronized void runTasks(int currentTick) {
  10.         this.parsePending();
  11.         while (!this.pending.isEmpty() && ((CraftTask)this.pending.peek()).getNextRun() <= (long)currentTick) {
  12.             long period;
  13.             CraftTask task = (CraftTask)this.pending.remove();
  14.             if (this.executeTask(task) && (period = task.getPeriod()) > 0L) {
  15.                 task.setNextRun((long)currentTick + period);
  16.                 this.temp.add(task);
  17.             }
  18.             this.parsePending();
  19.         }
  20.         this.pending.addAll(this.temp);
  21.         this.temp.clear();
  22.     }

  23.     private boolean executeTask(CraftTask task) {
  24.         if (CraftAsyncScheduler.isValid(task)) {
  25.             this.runners.put(task.getTaskId(), task);
  26.             this.executor.execute(new ServerSchedulerReportingWrapper(task));
  27.             return true;
  28.         }
  29.         return false;
  30.     }
复制代码


可见它用了线程池来执行任务


第一页 上一页 下一页 最后一页