[Tutorial] Multi threading - Using async events!

Discussion in 'Resources' started by bigteddy98, Nov 14, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    bigteddy98

    Tutorial - Using Async events without any problems

    Hi there,

    After I heard some people who had problems with multi threading code, I decided to write a little Tutorial to explain you how multi threading in Java works.
    In this tutorial I will show you how multi threading works, which includes writing thread safe code.

    To start, I am going to use the AsyncPlayerChatEvent. The player chat is running on another thread. The reason of this is that if your server is lagging, the players can still chat.

    Code:java
    1.  
    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerChat(AsyncPlayerChatEvent event){
    4. Player p = event.getPlayer();
    5. p.sendMessage("Hi!");
    6. }
    7.  


    As long as you aren't using anything which could be modified be another tread, you have no problems with non thread safe code. This could be, for example, sending a message to a player.

    If you have a field which can be modified by multiple threads, you have to pay attention for multi threading problems. This for example:

    Code:java
    1.  
    2.  
    3. public boolean chatIsOpen = false;
    4.  
    5. @EventHandler
    6. public void onPlayerChat(AsyncPlayerChatEvent event){
    7. Player p = event.getPlayer();
    8. if(this.chatIsOpen == false){
    9. event.setCancelled(true);
    10. }
    11. }
    12.  


    There is no problem with this code, as long as no other thread will change our boolean, chatIsOpen.
    If the boolean does get changed by another thread, at the same time as a player chats, it will cause a problem.
    The problem is that there are two threads using the same boolean.

    You can fix this by making the boolean volatile, this means that it can only be modified by one thread at the same time.
    This really sounds simple, but it can be very difficult. The main problem is that if the boolean is in use by thread number 1, thread number 2 will be sleeping as long as thread number 1 is using it.
    So if you make a field volatile, remember, if two threads are using the same field the second thread will be paused until thread number 1 is finished, which can cause problems.

    For methods it works almost the same, but for methods it's not volatile, but synchronized. synchronized can be very handy to protect a group of fields, from not being used at the same time, example:

    Code:java
    1.  
    2.  
    3. private Material mat;
    4. private int materialId;
    5.  
    6. public synchronized Material setMaterial(Material material){
    7. this.mat = material;
    8. this.materialId = material.getId();
    9. }
    10.  

    Because the method is synchronized there is only one thread at the same time which can modify the value of the material and the id.

    Just a little tip:
    99.99999% of the final fields are thread safe, when using multiple threads, try making as much as possible final.

    I hope this tutorial helped you and you won't have any trouble with multi thread coding, if you have any questions just leave them below ;).
     
    darkness1999, Yonas and SuperOmegaCow like this.
  2. Offline

    macguy8

    In your example, you're using PlayerChatEvent which is **always** sync. Only AsyncPlayerChatEvent can be async, but it might not always be (eg if another plugin fired the event). You should use also make sure the event is async (via a method)
     
  3. Offline

    bigteddy98

    Whoops! My bad, edited ;).
     
  4. Offline

    sebasju1234

    bigteddy98 - Great tutorial. keep up the good work Sander.
     
  5. Offline

    Panjab

    So in fact, use 'volatile' or 'synchronized', where 'synchronized' is still the better one though? Might should be added in one, bold sentence :)

    Well done ;)
     
  6. Offline

    bigteddy98

    Thanks Sebastiaan.
     
  7. Offline

    Yonas

    It's useful for many people like me. :)
     
  8. Offline

    Cirno

    A bit offtopic, maybe not even needed, but the java.util.concurrent package contains thread-safe(?) objects. If you're storing primitive data, use java.util.concurrent.atomic to allow modification with multi-threading.
     
  9. Offline

    xTrollxDudex

    Synchronized is mainly for method declarations, can be replaced by ReentrantLock if you know what you are doing. Volatile means that access to the field is blocked off until the the thread before it finishes.
     
Thread Status:
Not open for further replies.

Share This Page