I have a main thread that handles giving every player updated information when they open a gui. But I first need to sort that information every 30min which is done by a separate thread in order to not cause lag spikes on that main thread. Now my sorting algorithm clears a private static LinkedHashMap then I query the new data before adding all of the new entries to each map.
Now I know that the actual sorting is thread safe and I also know that my sortsMap() method will only be called once every 30min from my async thread. I think the only issue would be if a player opens a gui as I call the sortMaps() method asynchronously since it would be trying to clear data while its being read. I think this could be solved by using the synchronized keyword however I am not sure the best way to use it. If I make my sortMaps() synchronized I assume it would still cause issues since my async thread is calling sortMaps() while the main thread gui updater is calling the getter.
So how can I properly synchronize this so that the sortMap() method that it's being called asynchronously will wait to update the map till after the main thread is done querying the data and make the main thread wait to query the data till after I finish updating the maps. The following is a sort of sudo code of my issue so you can understand my structures but I removed most of the inner code since this is not an algorithm question.
private static final Map<String, Integer> sortedDataForGUI = new LinkedHashMap<>();
/**
* This method is called asynchronously every 30min
*/
public static void sortMaps() {
sortedDataForGUI.clear();
// Then I gather general player info before sorting and adding them to the map above.
}
/**
* This is called by the main thread when a player opens a gui
*/
public static Map<String, Integer> getSortedDataForGUI() {
return sortedDataForGUI;
}
What if I made a single method like the following so that I can my async thread can pass in true to update the data while my gui's can pass in false to get the info would this achieve everything I talked about above and is it the best way? I hope this made sense I have been just throwing out everything I thought of and everything I know since people on here respond poorly to questions where the poster never made any attempts.
public static synchronized Map<String, Integer> getSortedMap(boolean sort) {
if(sort) {
// My sorting algorithm would go here which is only called asynchronously.
}
return sortedDataForGUI;
}
Edit: Due to the comment bellow I added some extra sudo code to depict me trying to take info from two separate maps and sort them based on value. Keep in mind one takes in an Object as the value while the other takes in an Integer. Previously to this I used a comparator with a linkedList in order to sort my map however it seems like I now need to include my comparator as a parameter to my ConcurrentSkipListMap but I dont know exactly how to do that.
public static void sortMaps() {
final ConcurrentSkipListMap<String , Integer> maps = new ConcurrentSkipListMap<>();
for(Map.Entry<String, Integer> map1 : DataManager.MEMBER_DATA.entrySet()) {
maps.put(map1.getKey(), map1.getValue());
}
for(Map.Entry<String, MemberObject> map2 : DataManager.LAST_MEMBER_DATA.entrySet()) {
maps.put(map2.getKey(), map2.getValue().getNum());
}
}