@@ -5,17 +5,18 @@ layout: default
55
66# Writing a multithreaded plugin
77
8- The Minecraft server runs game code primarily on a single thread. This is huge limitation as a single thread can only be so fast.
8+ The Minecraft server runs game code primarily on a single thread. This is huge limitation as a singular thread can only be so fast.
99
1010Luckily, there are server cores that allow the game code to run on multiple threads.
1111These include [ Folia] ( https://papermc.io/software/folia ) and [ ShreddedPaper] ( https://github.com/MultiPaper/ShreddedPaper ) .
12+ However, a normal Bukkit plugin will not work on these server cores, and needs to be rewritten to have a multithread environment.
1213
1314## What is a thread?
1415
1516### Single threaded
1617
1718A thread is what your code executes on. One thread can execute one piece of code at a time.
18- This means if your plugin is single-threaded, only one part of the plugin will be executing at a given time.
19+ This means if your plugin is single-threaded, only one part of the plugin will be executed at a given time.
1920
2021``` mermaid
2122flowchart LR
@@ -122,9 +123,19 @@ if (Bukkit.isOwnedByCurrentRegion(entity)) {
122123}
123124```
124125
126+ ### Asynchronous calls
127+
128+ Asynchronous calls can be made with:
129+
130+ ``` java
131+ Bukkit . getAsyncScheduler(). runNow(plugin, t - > {
132+ // Async code goes here
133+ });
134+ ```
135+
125136### Tips
126137
127- During most events and commands, you will be on the thread of the player/entity/block that triggered the event or ran the command.
138+ During most events and commands, you will be on the thread of the player/entity/block that triggered the event or command.
128139
129140## Java gotchas for multithreaded plugins
130141
@@ -163,21 +174,52 @@ This makes sense. However, if the method `nextPlayer` is running on two threads
163174
164175This shows the issue of race conditions and why you need to try to avoid them
165176
177+ ### Synchronized statement
178+
179+ To avoid race conditions, you may need to make sure your code is only executing on one thread at a time.
180+ A ` synchronized ` statement solves this by locking the given Java object. For example:
181+
182+ ``` java
183+ final Object lockObject = new Object ();
184+ Player player;
185+
186+ void nextPlayer() {
187+ synchronized (this . lockObject) {
188+ // This block of code will only run once at a time for any `this.lockObject`
189+ Player nextPlayer = this . getTheNextPlayer(this . player);
190+ nextPlayer. sendMessage(" You are now the player!" );
191+ this . player = nextPlayer;
192+ }
193+ }
194+ ```
195+
196+ You can also lock the object that holds the method as so:
197+
198+ ``` java
199+ Player player;
200+
201+ synchronized void nextPlayer() {
202+ // This block of code will only run once at a time for the object containing this method
203+ Player nextPlayer = this . getTheNextPlayer(this . player);
204+ nextPlayer. sendMessage(" You are now the player!" );
205+ this . player = nextPlayer;
206+ }
207+ ```
208+
166209### Data types
167210
168- Common data types are typically ** not** multithread safe. For example:
211+ Common data types are typically ** not** multithread safe.
212+ This means only one thread can safely access them at a time.
213+ For example:
169214- ` ArrayList `
170215- ` LinkedList `
171216- ` HashMap `
172217- ` HashSet `
173218
174- Consider these following thread-safe data types instead:
219+ If you need multiple threads to be able to access the data types at the same time,
220+ consider these following thread-safe data types instead:
175221- ` Collections.synchronizedList(new ArrayList()) `
176222- ` CopyOnWriteArrayList `
177223- ` LinkedBlockingDeque `
178224- ` ConcurrentHashMap `
179225- ` ConcurrentHashMap.newKeySet() `
180-
181- ### Locks
182-
183- Locks
0 commit comments