0

The point of this thread is so I can learn the most optimized way to handle a task and whether multithreading in this scenario improves or decreases performance. Anyways I have a private LinkedList inside one of my objects which holds objects that denote a specific task a player needs to complete. Every one hour I then change the tasks for every player and I am wanting to know if its better to do this on the main thread or if its better to do it asynchronously.

It firsts clears the list then runs an algorithm I made to pick randomly tasks and add the newly created task objects to the list for every player in my game. Since this is on the main thread when this happens my games server cant process any other info till its complete. I did optimize it so it should be fast and should work either way however this is more about me wanting to learn the optimal solution then just making it work.

So I could either run everything on the main thread or I could make my linkedList's getter synchronized and run that algorithm on a separate thread. How much overhead do synchronized methods produce especially if they are called often? I cant use a ConcurrentSkipListSet since it is similar to a normal Set where I cant access a specific index with .get() which means I would need to do a lot of looping which seems worse than the other 2 options. What is the best methodology here and going forward for me to decide when its better to use synchronized with multiple threads vs just using the main thread?

  • 2
    How long does it have for the 'hourly housekeeping' to execute? Until you've measured it and found it unacceptable, speculation about improvements are pointless. – access violation Aug 27 '22 at 01:43
  • You might want to read about [Amdahl's law](https://en.wikipedia.org/wiki/Amdahl%27s_law). Can you use an `ArrayList`? Because that's backed by an array. Which will probably work better for you. – Elliott Frisch Aug 27 '22 at 01:46
  • @ElliottFrisch No I need it to be ordered with a LinkedList but I could change things around to make it work with a normal ArrayList but I dont see how that helps much. – IDontWantToMakeAnotherAccount Aug 27 '22 at 02:53
  • "wanting to learn the optimal solution" Optimising for what exactly? – tgdavies Aug 27 '22 at 02:59
  • @accessviolation Are you asking how long it takes to execute? Well it scales with player count so I cant say for sure. Well I want to know how much overhead the synchronized keyword adds to the execution of methods. Is there no general scenario where one is better than the other? I thought this would be a common scenario which has been tested in the past. For example does one of the methods above work better under high volume over low volume because that would not be dependent on my specific case just dependent on the time it takes to complete running its code. – IDontWantToMakeAnotherAccount Aug 27 '22 at 02:59
  • I used to work on a MUD in Java. My choice was to use a separate process for each player instance and one instance for NPCs and MOBs (don't know if you know the terminology for MUDs) If you're working on a multiplayer system, using a thread for each player is a must. You can still make it work with a single thread, but that can produce lag if there're many players connected (because you need all the actions before yours to be computated). Consider that computers nowadays have multiple processors, and multithreads should make it easier for the VM to use more than one processor. – Luca Scarcia Aug 27 '22 at 03:02
  • @tgdavies Well I enjoy learning and want to know when synchronizing my methods while using another thread beats using a single thread. How much over head is there with synchronizing methods? Does synchronizing with another thread beat single threaded processing every time or does it depend on how often that other thread runs and how much work that other thread does? – IDontWantToMakeAnotherAccount Aug 27 '22 at 03:03
  • See https://stackoverflow.com/questions/8521819/performance-of-synchronize-section-in-java – tgdavies Aug 27 '22 at 03:07
  • @LucaScarcia The server thread needs to be single threaded since thats where the server clock but I have a dedicated thread pool that handles packets and each player has their own anti cheat thread. But keeping the core game world interactions on the main thread ensures everything stays in sync without race conditions. However this question is pertaining to that single world thread where I want to know if I should make runnable on a separate thread or keep it single threaded. The main issue is I dont know which option is better. – IDontWantToMakeAnotherAccount Aug 27 '22 at 03:10
  • @tgdavies Yes I already read that before making this post but it never mentioned when either approach is better. I would think that the answer might be different depending on how often the second thread runs and how long it takes to run. If my 2nd thread only runs once an hour would the constant calls from my main method to a synchronized getter method actually be slower? – IDontWantToMakeAnotherAccount Aug 27 '22 at 03:16
  • Well, MUDs are somehow streamlined, so having a single process for all the "world" operarions is certainly better. The only thing that I would put in a separate process is the repopulation of the world (in MUD we repopulate the whole area). If you have already separated the player processes, than I'd answer that it's better to put everything in a single process. But, again, slow and long operation perhaps should be put in separated threads to avoid lagging the world. – Luca Scarcia Aug 27 '22 at 03:38
  • @LucaScarcia I am not sure what MUD is but yea I agree world generation is good to add to a separate thread. I always thought that I should handle large bulk operations on a separate thread so I am glad you agree. Is there a way I can make it prioritize the main thread so that when my separate thread gets the data it will create a new list then run everything on that second thread then wait for the main thread to not be accessing the list and then assign the new list equal to the old list? That way I dont lose any performance on the main thread since I can afford to make my 2nd thread wait. – IDontWantToMakeAnotherAccount Aug 27 '22 at 04:02
  • MUD or Multi User Dungeon is a textual multiplayer game based on AD&D. For your question, I think you should use a second list when creating and then simply add in a single swoop all the items to the world list at the end of the process. That way the population process will monopolyze the list for the minimum time possible. I'm not sure if there're ways to prioryze a process in Java, but if you actually place the items in the world at the very end of the process, that would minimize the lag for the players. That would work in general. Use the shared resources only at the very end. – Luca Scarcia Aug 27 '22 at 04:35
  • @LucaScarcia Yea that is a good idea I just wished there was a way I could lock and unlock with my 2nd thread which would remove the overhead of synchronization while reducing the performance of my 2nd thread (which is fine since all I care about is my main thread). – IDontWantToMakeAnotherAccount Aug 27 '22 at 05:06
  • You could add a simple semaphore, a true/false flag that inhibits the first tread to read while the second is still working on the resource. Still syncronize should be optimized, so I don't know how much overhead you are really removing doing so. If syncronization is critical to your game, you just have to try to optimize somewhere else... In example, avoiding cycles and conditional brench whenever possible, using index and precalculated tables. – Luca Scarcia Aug 27 '22 at 15:14
  • There's a good answer on this similar question, posted later: https://stackoverflow.com/q/73508501/29470. I'll vote to close this one as a duplicate. – Tim Moore Aug 28 '22 at 02:13

0 Answers0