Neige
本帖最后由 Neige 于 2022-1-8 21:59 编辑

经历今天的事件,我可能再也不会runTask()了。遇事不决Bukkit.getScheduler().callSyncMethod()就完事儿了
bukkit的东西基本碰不得异步,所以想要异步就得在里面套一层同步。——之前看插件开发教程,我深深地记住了这一点。
于是我就遇到了今天的诡异事件。先大概描述一下当事代码()
  1. // 构建一个石头
  2. var itemStack = new ItemStack(Material.STONE)

  3. // 异步把石头给玩家1000次
  4. function test(){
  5.     var test = Java.extend(BukkitRunnable, {
  6.         run: function() {
  7.             // 当前时间
  8.             var aaa = new Date().getTime()
  9.             for (var i = 0; i < 1000; i++) {
  10.                 ItemGiverAsyn(sender, itemStack)
  11.             }
  12.             // 耗时
  13.             print (new Date().getTime() - aaa)
  14.         }
  15.     })
  16.     new test().runTaskAsynchronously(Pouvoir)
  17.    
  18. }

  19. function ItemGiverAsyn(player, itemStack){
  20.     var inv = player.getInventory()
  21.     var loc = player.getLocation()
  22.     var dropList = inv.addItem(itemStack)
  23.     if (!dropList.isEmpty()) {
  24.         // 在主线程丢掉落物
  25.         var ItemDrop = Java.extend(BukkitRunnable, {
  26.             run: function() {
  27.                 loc.getWorld().dropItem(loc, dropList[0])
  28.             }
  29.         })
  30.         new ItemDrop().runTask(Pouvoir)
  31.     }
  32. }
复制代码

然后我跑了一下,后台的反应是这样的

嗯。嗯。。嗯。。。嗯??????
总之就是经历了长久的测试,最后最后一部分代码改成了
  1. function ItemGiverAsyn(player, itemStack){
  2.     var inv = player.getInventory()
  3.     var loc = player.getLocation()
  4.     var dropList = inv.addItem(itemStack)
  5.     if (!dropList.isEmpty()) {
  6.         // 在主线程丢掉落物
  7.         BukkitScheduler.callSyncMethod(Pouvoir, function() {
  8.             loc.getWorld().dropItem(loc, dropList[0])
  9.         })
  10.     }
  11. }
复制代码

后台的反应是。。。


这两段代码唯一的区别就是最后的主线程掉落物品。。。
一个能从3秒卡到13秒,另一个能从6ms飚到2ms。。。
()大脑,停止了思考。

这到底是为什么







Panzako
因为 runTask 会将你的任务放置在调度器里
在下一个服务器onTick 时执行,而MC的一个tick至少50ms
而callSyncMethod则是尽快执行

Neige
Panzako 发表于 2022-1-8 23:03
因为 runTask 会将你的任务放置在调度器里
在下一个服务器onTick 时执行,而MC的一个tick至少50ms
而callSy ...

不太明白为什么会越来越慢。这个递增的耗时就算静置几个小时依然存在

超級寶寶
异步的話不會有這問題但不能异步
bukkit的原始代碼把所有東西都塞進同一線程 本身就有延遲
本來就已經很多了在塞個新的task進去 延遲就會更久

Neige
超級寶寶 发表于 2022-2-8 11:19
异步的話不會有這問題但不能异步
bukkit的原始代碼把所有東西都塞進同一線程 本身就有延遲
本來就已經很多 ...

可是就算任务执行完了,他消耗的时间也越来越久。无法理解

耗子
从Bukkit的源码来看,runTask和callSyncMethod的执行方式并无区别,均是将任务置于调度器中,我认为可能存在以下问题:
(1)测试方式有误,两者测试条件不一致。
(2)时间获取方式有误,导致时间计算错误。
(3)JavaScript对Java类继承存在性能问题,为啥放着Java不写非要写JavaScript。

Neige
耗子 发表于 2022-2-8 13:34
从Bukkit的源码来看,runTask和callSyncMethod的执行方式并无区别,均是将任务置于调度器中,我认为可能存 ...

有可能是第三种。
条件是一致的,而且时间是肉眼可见地拉长。一二应该不是

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