plspl plspl - 5 months ago 34
Java Question

Java synchronization in web service

I have a java restful webservice program thats hosted on tomcat. In one of my web service methods, I load a big arraylist of objects (about 25,000 entries) from redis. This arraylist is updated once every 30 mins. There are multiple threads reading from this arraylist all the time. When, I update the arraylist I want to cause minimum disruption/delays since there could be other threads reading from it.

I was wondering what is the best way to do this? One way is to use synchronized keyword to the method that updates the list. But, the synchronized method has an overhead, since no threads can read while the update is going on. The update method itself could take few hundred millisecs since it involves reading from redis + deserialization.

class WebService {

ArrayList<Entry> list = new ArrayList<Entry>();

//need to call this every 30 mins.
void syncrhonized updateArrayList(){
//read from redis & add elements to list
}

void readFromList(){
for(Entry e: list) {
//do some processing
}
}

}





Updated the final solution:
I ended up using no explicit synchronization primitives.

Answer

Here is the solution I finally ended up with,

class WebService {

 // key = timeWindow (for ex:10:00 or 10:30 or 11:00), value = <List of entries for that timewindow>
 ConcurrentHashMap<String, List<Entry>> map= new ConcurrentHashMap<String, List<Entry>>();

    //have setup a timer to call this every 10 mins.
    void updateArrayList(){
     // populate the map for the next time window with the corresponding entries. So that its ready before we start using it. Also, clean up the expired entries for older time windows.

    }

    void readFromList(){
      list = map.get(currentTimeWindow)
      for(Entry e: list) {
       //do some processing
      }
    }

}