XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Другие игры (только чтение)> Minecraft
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

 
DioD

offline
Опыт: 45,251
Активность: 924
Участник проектов:
-WarCraft 3
-Minecraft
CraftBukkit concurrency
Before reading this article check:
C) You favorite "java for dummies book";
I wont explain how JVM works, articles above contains that information, i will explain how exactly minecraft server vanilla and xBukkit works:
  1. Entry point:
Every application must have single entry point, this is in case of java (in most cases) main(String...) method of some class.
NOTE: (String...) equals (String[]{}), it's just different way to write things down.
When you pass xBukkit jar to your JRE, it reads MANIFEST.MF file contained inside META-INF folder of jar, you can check it by any application that can read zip archives.
In case of craftbukkit jar main class declaration is:
"Main-Class: org.bukkit.craftbukkit.Main"
Applets and embedded web applications run in diffrent way, unjared classes passed to JVM directly.
Entry point preinit will create new thread, this is main thread of application created by JVM, termination if main thread will cause JVM termination if no other nondaemon thread are alive.
Exception terminates thread.
It's possible to create watchdog threads and "reboot" application in case of error, also it's possible to perform "postmortem" actions before JVM is terminated (running shell\cmd to restart server) or cancel termination completely.
  1. Creating new threads:
You are free to create additional threads in java without help of xBukkit API, but such threads will be completely async with servers's main thread, with risk of memory ABA errors and other stuff you dont want.
I will use anonymous class feature ( docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.htm... ) in order to reduce amount of class declarations in next samples (classes are declared anyway by compiler).
You shoud declare separate class each time, in other case you will end with ugly hardtoread code.
This sample of code, that will watch main application thread and restart application in case of failure:
Main points explained:
In order to keep threads alive, you must use while(true) or for(;;), in other case thread will be terminated as soon as all actions are completed.
Recursive method invocation (invoke itself as last line) not recommended, few costly JVM operations wrap this process, also doing it wrong will cause stackoverflow error after some time.
To keep your application stable you must use Thread.sleep(long) or similar invocation, in other case your thread will execute as fast as it can.
In some cases (IOpump) execution without delay usefull, but not for bukkit.
There are two "similar" methods:
.start - will start concurrent execution (new separate thread)
.run - will start sequential execution (just invoke "run" method)
Soo most minimal construction:
[code]
for(;;){
"action"
Thread.sleep(100L);
}
[/code]
  1. xBukkit main thread:
Main class " org.bukkit.craftbukkit.Main" will preform some actions and pass control to "net.minecraft.server.MinecraftServer".
Main server loop definition contained inside "public void run()", you can find it inside xBukkit source code (watch for "while (this.isRunning)");
It tick with 1L timeout and pass control (in most cases) every 50th tick to "worldmanager".
It may tick multiple times at once in some cases, number of ticks tracked.
Other threads also exists, but they not joined with main thread and run in async.
As stated above, control passed to "worldmanager" every 50th tick, 1000\50 = 20 executions per second.
This is answer for "why there are 20 ticks per second".
If anything hold, pause, wait or sync main thread - it will halt and wont pass control to "worldmanager" and next ticks also will start later, game wont "increase time" to compensate.
This effect especially noticeble with WorldEdit or similar "heavy" plugins, they may freeze entire server for seconds.
Most plugin developers use tasks to track time and "count" single tick for 50 ms, now you know why they are wrong.
  1. Bukkit tasks:
"worldmanager" tasklist included invocation of CraftBukkit task factory:
"this.server.getScheduler().mainThreadHeartbeat(this.ticks);"
Старый 27.12.2013, 21:20

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 14:09.