Tutorial by: DjDisaster


What is async? Async is running operations off of the main thread.
Why use async? This allows for certain code to run without effecting performance on the main thread.
When to use async? Async can be good when you don't need to run bukkit methods. Bukkit is not very thread-safe so you will get issues when using some methods.
How to check whats thread-safe? You can try running it async and if you see a stacktrace (large amount of red text with error) in your console its not thread safe.
An example of what is thread safe: Particles
An example of what is not thread safe: spawning an entity

What is async good for? Async is very good for operations such as leaderboards, skript is fairly inefficient and can take some time to sort through leaderboards. The added sorted method does help but its still something you should do async. This will prevent it from causing your server to freeze.

For this tutorial I will be using ExecutorServices which is a wrapper over the Thread class. This simply gives more control over how it works.

import:
    java.util.concurrent.ExecutorService
    java.util.concurrent.Executors
    ch.njol.skript.Skript
    java.lang.Runnable

These are the imports you will generally need, now we need to register an ExecutorService in order to use it.

on load:
    if {Threads::Thread1} is not set:
        set {Threads::Thread1} to Executors.newFixedThreadPool(1)

This will then allow us to send tasks to the executor for it to then process on the other thread.

I generally use functions as its generally easier than sections, you could implement this with a section as well though.

function UpdateThreadded():
    set {_functions::run} to function reference "RunUpdateThreadded"
    set {_runnable} to new proxy instance of Runnable using {_functions::*}
    {Threads::Thread1}.submit({_runnable}

This will run the function RunUpdateThreadded on Thread1.

Now we just need some code to run in the RunUpdateThreadded function.
This can be anything as long as its thread safe. Such as:

function RunUpdateThreadded():
    broadcast "hello world"

Now, about thread safety, what if we want to be able to run methods that aren't thread safe?
We will have to run them on the main thread. This will mean we need to do 1 of 2 approaches.
1: Make a section and call it sync and wait for the response
2: Add a wait 1 tick which will make the rest of the function sync

It is worth noting that any delay such as wait 1 tick will make the code go back to sync (on the main thread).

Example:

function RunUpdateThreadded():
    set {_gui} to chest inventory with 6 rows named "<##FF0000>&lEpic Gui"
    set slot (all numbers between 10 and 16) of {_gui} to orange terracotta named "My Epic Gui's Item"
    wait 1 tick
    # you need to define the player here, you can simply add arguments to the function
    # and call the function using set {_functions::run} to function reference "FunctionName" called with {_arg}
    # you can also do {_arg}, {_arg2} and {_arg3} or whatever you need.
    open {_gui} to {player}

Showing a gui to a player is not thread safe but creating one is. So this can create the GUI async and then
Show it to the player sync


Did you find DjDisaster's tutorial helpful?


You must be logged in to comment