Home > Back-end >  How to print a map and clean it being thread safe?
How to print a map and clean it being thread safe?

Time:03-08

I am currently working on a thread-safe development and I am a bit blocked due to my little experience in java :(

Basically I have a Shedule class where every so often I load a ConcurrentMap print that data and then delete. I have it as follows:

  @Scheduled(
    fixedDelayString = "1000",
    initialDelayString = "1000"
  )
  public synchronized void run() {

    ConcurrentMap<String, DataObject> currentData =  data.getCurrentData();

    messagePrinter.print(currentData );
    messageData.clearData(); //PROBLEM!! Possible data added after printing
  }

The problem here is that this is not a thread safe, because after printing the data when I want to clean it is possible that there is data stored in another thread that was not printed and delete data that I need.

Is there any way to be able to print and then delete all the data being thread safe?

Thank you in advance

CodePudding user response:

You could create a copy of the current state, then print the data and finally remove the elements that where present at the time you made a copy.

        ConcurrentMap<String, DataObject> currentData =  data.getCurrentData();
        ConcurrentMap<String, DataObject> copy = new ConcurrentHashMap<>(currentData);
        messagePrinter.print(copy);
        copy.forEach((key, value) -> currentData.remove(key));

Be aware that this might only work if the key of the map is always unique. Else you might still remove new data.

CodePudding user response:

If currentData and messageData are supposed to be the same variable then you should copy the map. If you don't then you could get concurrency issues when another thread tries to modify the map in data. Even better would be to have the data.getCurrentData() method return a copy of the data itself just in case the API client doesn't create their own copy, which would help make your data class immutable. You can also use currentData.clear() to clear the map.

If they are not the same variable and are two distinct objects which can access the map, then an option would be to encapsulate the data in a single class, where get and write operations on the data only occur through the class's public api. If you do this then you could have a method which gets and clears the data in a single operation such as getAndClear(). That method could be synchronized or you could synchronize the method's logic on the data map.

  • Related