Skip to content

Commit 4d40a90

Browse files
authored
Update writing-a-multithreaded-plugin.md
1 parent ee431c9 commit 4d40a90

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

docs/writing-a-multithreaded-plugin.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1010
Luckily, there are server cores that allow the game code to run on multiple threads.
1111
These 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

1718
A 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
2122
flowchart 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

164175
This 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

Comments
 (0)