我正在开发一个Web应用程序,其中一个名为CheckURL的servlet将在其init方法中从xml文件中读取一些数据,并将来自此xml的节点列表放在servletcontext中。因此,每个进入此servlet的请求都不必一次又一次地从xml中读取数据。它可以从servletcontext获取节点列表。应用程序中有另一个servlet用于更新xml,如果更新了xml,我将更新servletcontext nodelist变量。
因此,在这种情况下,我希望进行同步以确保在写入xml时,应该阻止来自servletcontext节点列表的任何读取。如果不是,它可能正在读取不是最新的数据。
为实现这一目标,我想知道我应该使用哪个同步级别。我应该在servletcontext对象上进行同步,还是应该在servlet上下文中的元素集上进行同步,还是应该在servlet类实例上进行同步。
答案 0 :(得分:1)
你可以做的是拥有一个类,它是一个线程安全的包装器,可以访问进出ServetContext
这个类可以使用
java.util.concurrent.locks.ReentrantReadWriteLock
仅锁定读取和写入节点列表。
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();
}
}
}
备注强>:
ServetContext
答案 1 :(得分:1)
出于性能原因,建议尽可能将同步范围尽可能小。较少的代码块执行的时间较少,而其他线程等待的时间较少。
在这种情况下,您应该在nodeList级别上进行同步。您可以使用包含节点列表的Collections.synchronizedList
。它将完成原子操作的所有同步工作。但是,要在列表上执行多个操作作为一个原子操作,您将需要显式同步。例如,当你读写时。查找代码示例here。