I have the following class. I am using ConcurrentHashMap. I have many streams writing to cards, and a timer that saves data on the card every 5 minutes. I manage to achieve thread safety using putIfAbsent () when I write entries on the map. However, when I read it and then delete all the records using the clear () method, I do not want any other thread record to appear until Im in the process of reading the contents of the map and then deleting them. Obviously, my code is not thread safe even with a synchronized (lock) {}, b / c stream, which owns the lock in the saveEntries () file, is not necessarily the same stream that writes my cards to the log () method ! If I lock all the code in log () with the same lock object!
I was wondering if there is another way to achieve thread safety without forcing synchronization with an external lock? Any help is appreciated.
public class Logging { private static Logging instance; private static final String vendor1 = "vendor1"; private static final String vendor2 = "vendor2"; private static long delay = 5 * 60 * 1000; private ConcurrentMap<String, Event> vendor1Calls = new ConcurrentHashMap<String, Event>(); private ConcurrentMap<String, Event> vendor2Calls = new ConcurrentHashMap<String, Event>(); private Timer timer; private final Object lock = new Object(); private Logging(){ timer = new Timer(); timer.schedule(new TimerTask() { public void run() { try { saveEntries(); } catch (Throwable t) { timer.cancel(); timer.purge(); } } }, 0, delay); } public static synchronized Logging getInstance(){ if (instance == null){ instance = new Logging(); } return instance; } public void log(){ ConcurrentMap<String, Event> map; String key = ""; if (vendor1.equalsIgnoreCase(engine)){ map = vendor1Calls; }else if(vendor2.equalsIgnoreCase(engine)){ map = vendor2Calls; }else{ return; } key = service + "." + method;
}
source share