0

I'm working on a web application in which a servlet named CheckURL will read some data from a xml file in its init method and will put the node list from this xml in the servletcontext. So every request coming to this servlet would not have to read data from the xml again and again. It could just get the node list from the servletcontext. There is a another servlet in the application which is used to update the xml and I will update the servletcontext nodelist variable if xml is updated.

So in this scenario, I would like to have synchronization in place to make sure that, when writing to the xml happens, any reading from the servletcontext nodelist should be blocked. If not it might be reading data which is not up to date.

To achieve this, I am wondering which synchronization level should I be using. Should I synchronize on servletcontext object or should I be synchronizing on the element set in the servlet context or should I be synchronizing on the servlet class instance.

KItis
  • 5,476
  • 19
  • 64
  • 112
  • Synchronize on the `ServetContext`. – user207421 May 25 '16 at 02:14
  • @EJP I am wondering, synchonizing on servletcontext would slow down the application in my view. Since servletcontext object may have been used by other servlets as well and my read or write operations to nodelist should not block reading and writing to other variables stored in the servlet context. – KItis May 25 '16 at 02:18
  • 1
    You're overthinking this. It would only show down those parts of the application that are also synchronizing on the same thing, and only by the amount of time spent in the synchronized block. How long does it really take to update a context variable? – user207421 May 25 '16 at 02:52

2 Answers2

1

What you can do is have a class that is a thread-safe wrapper around access to the node list object that is going in and out of the ServetContext

This class can make use of a

java.util.concurrent.locks.ReentrantReadWriteLock

to lock just the reading and the writing of the node list.

public class ThreadSafeAccessToNodeList
{
   private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

   private final Lock readLock = readWriteLock.readLock();
   private final Lock writeLock = readWriteLock.writeLock(); 

   public NodeList read (ServetContext sc)
   {
       readLock.lock();
       NodeList nl = null;
       try
       {
           // get the node list
           nl = (NodeList) sc.getAttribute("node_list");
       }
       finally
       {
            readLock.unlock();
       }
       return nl;
   }

   public void write (ServetContext sc, Object newData)
   {
       writeLock.lock();
       try
       {
           // get the node list
           NodeList nl = (NodeList) sc.getAttribute("node_list");

           // modify the node list with the new data
       }
       finally
       {
            writeLock.unlock();
       }    
   }
}

Notes:

  • This has the benefit of not synchronize on the entire ServetContext
  • Also, this lock performs best when there are more readLocks required as compared to writeLocks.
Michael Markidis
  • 4,163
  • 1
  • 14
  • 21
1

Synchronization scope is recommended to be as minimal as possible for performance reasons. Less chunk of code takes less time to execute and less time for other threads to wait.

On this case you should synchronize on nodeList level. You can use Collections.synchronizedList which will contain node list. It will do all synchronization work for atomic operations. However, to perform multiple operation on the list as one atomic operation you will need explicit synchronization. For example, when you read-and-write. Look for code example here.

Community
  • 1
  • 1