Thread-safe API methods.

Discussion in 'Plugin Development' started by DrAgonmoray, Jan 29, 2012.

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

    DrAgonmoray

    Hi. I don't really know much about multithreading, so I really don't know how to check the source to see if they are safe.
    Doing a quick google search, I found that these are thread-safe methods:
    Code:
    All the scheduler methods
    Bukkit.getServer()
    Server.getBukkitVersion()
    World.getUID()
    World.getMaxHeight()
    World.getSeed()
    World.getBlockTypeIdAt(int x, int y, int z)
    Entity.getEntityId()
    Entity.getUniqueId()
    One of the methods I was going to ask about (getBlockTypeIdAt()) is in that list, so that's good.
    Are BlockIterators thread safe? I'm going to be using those a lot, and doing many calculations so I'm hoping that I can put that load on another thread.

    I know that I can't update blocks using threads, so could somebody explain to me how I would do this:
    1. Get data on a separate thread (location and type of blocks)
    2. Exit the thread with the data
    3. Use the data and perform block updates or other API methods
    Like I said before, I don't know much about multithreading, so this is a challenge for me.

    ---

    Looking at this post, it seems I'm kindof rambling, but hopefully I was clear enough. Thanks in advance for any help!
    bergerkiller (you're some kind of wizard :D)
     
  2. Offline

    Waterflames

    I don't know about blockiterators, but I do know that messing with list iterators in multithreading causes a ConcurrentModificationException to be trown. If that should be a problem, look into synchronization.
     
  3. Offline

    DrAgonmoray

    errr that's not what I was asking (probably my fault)
    I actually found the list on that page :p
    thanks though
    Wouldn't that only happen if I have 2 threads changing it? (I really don't know)
     
  4. Well that shouldn't be a problem as they are all get methods. Hence why they are thread safe.
     
  5. Offline

    DrAgonmoray

    Ok so get methods are thread safe. I figured that, but wasn't sure. Thanks!
    Do you know if BlockIterators are thread-safe? I'm not entirely sure how they work, but isn't it just "getting" the block in an iterative way?
     
  6. Offline

    bergerkiller

    DrAgonmoray getting the chunk from the server is thread-save, but loading one isn't. The BlockIterators use world.getBlockAt, which indirectly loads the chunk, causing the chunk_load event. Therefore it is not safe to use BlockIterators UNLESS all chunks contained are loaded (block radius of the max distance?) and are kept loaded (cancel the unload event of these chunks)

    If you have doubts, follow the following guide to check if it is safe:
    5 is a tough one. Take this for example:
    Code:
    //main:
    public String name = "hello";
     
    public void doStuff() {
        if (name != null) {
            name = name.substring(1);
        }
    }
    If you change 'name' while the main thread is running doStuff(), it might get past the null check and fail afterwards. This is the case with the entity remove() function, which sets the entity dead. Luckily it is not such a problem if it happens, since no other values are changed with it.
     
  7. Offline

    DrAgonmoray

    Ah, very good to know, thanks.
    I'm going to be using block iterators when TNT explodes. I'm wondering that since the chunk has to be loaded for the tnt to explode (am I right?), will I need to make sure the chunk is loaded?
     
  8. Offline

    bergerkiller

    Yup, otherwise the chunk is loaded on another thread, which is not multi-thread safe. (if it is then a lot of plugins will have to change)
     
  9. Offline

    samp20

    One thing you could try is Chunk.GetChunkSnapshot in the main thread, then work with that snapshot in another thread.
     
  10. Offline

    DrAgonmoray

    Hm.. I'm wondering if I should just change my approach to this problem all together.
     
  11. Offline

    bergerkiller

    samp20 Possible, but it does clone the data, which adds 80+ kb per chunk. Depending on the amount of chunks you operate on, this can become quite a lot. And you probably don't even need to copy the lighting information, heightmap or sub-id block data.
     
  12. Offline

    567legodude

    So as long as you don't need the bukkit api.
    Would it be safe to send a player a message?
    Or call a method that sets a score on a scoreboard. (Sets the score in a method outside the scheduler)
     
  13. Offline

    teej107

    ferrybig likes this.
  14. 567legodude Also, how you imagine you're going to do those things without the Bukkit API I'm not sure.
     
    Skionz likes this.
  15. Offline

    mythbusterma

    567legodude

    In general, the only things that can be guaranteed to be safe are things that are immutable, for example the UUID of a Player or World.

    ...or things that are explicitly stated as such, as Rocoty pointed out.
     
  16. Offline

    Rocoty

    mythbusterma If it's well documented that something is thread safe it can also be considered so. But that is no guarantee that it will be thread safe. In general one should trust good documentation, though.
     
Thread Status:
Not open for further replies.

Share This Page