My Plugin has quite a lot of commands. Especially executing them or listing all commands to show in help (or other kinds of information gathering) might take a bit longer. I’m now creating a new thread everytime a command has to be processed and it works quite well. Do you think this is good or bad for the overal server performance?
Threads have quite a bit of creation overhead, you should consider using the Scheduler’s async Executor to submit your tasks as Runnables.
Also what sort of commands are you executing? Almost anything that interacts with the API is a bad idea to multithread because MC has very little support for concurrency.
Ok. I’m going to do it with a scheduler
I didn’t know that could be a problem. I’ll only use it for data gathering and processing then.
So far I haven’t had any problem, even with api interactions. What do you mean by “bad idea”? Will it break or is it bad for performance?
In a nutshell you should always use async tasks for
- io/nio operations
- Every time you want to establish a connection (http request (outcoming and incoming), database connection)
- Every time you want to read/write to a stream
- Heavy calculations (multiplication of large matrix…)
Ok. Thank you (I sadly can’t mark two answers as solutions)
Also commands have no native support to be async. Making every command async by default will cause you to have to return CommandResult.Success for anything that is processing even if it is too early to tell.
I imagine (but don’t know for sure) that this could cause issues with command blocks, RCon, and other plugins that might be calling your commands for whatever reason.
I always return CommandResult.Success
because I created a custom command system (with parsing and suggestions). Also I now only use async for heavy statistic calculations and the broadcast of messages to all players that depend on whom they are send to etc…
The lack of concurrency will most likely give you data races, where the results of a method will change depending on exactly when it is run. This occurs because the MC thread is modifying data and does not expect it to be accessed during the operation. The second thread could see data in an invalid state because it is not forced to wait for the operation the MC thread is performing to be over.
A second issue is thread local memory. Unless explicitly told to do so, the JVM does not always make some changes to the memory by one thread immediately visible the others.
I’m only calculation data from my plugin
This applies to any number of threads that share data.