我写了一个名为AbcServlet.java
的Servlet,在其中有一个名为cacheSeller
的静态字符串字段。该字段在servlet的init
和doGet
方法中被填充,同时它也可以通过如下所示的CacheSellerClearThread.java
线程进行清空:
AbcServlet.java
public class AbcServlet extends HttpServlet {
private static String cacheSeller = null;
@Override
public void init() throws ServletException {
super.init();
cacheSeller = populateCacheSeller();
}
/**
* As soon as multiple requests are coming doGet is being called
*/
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
synchronized (this.getClass()) {
if (cacheSeller == null) {
cacheSeller = populateCacheSeller();
}
}
}
private String populateCacheSeller() {
String fetchItFromSomewhere = "";// some logic to fetch the sting
return fetchItFromSomewhere;
}
public static synchronized void clearCacheSeller() {
cacheSeller = null;
}
}
CacheSellerClearThread.java
/**
* This thread is clearing the string field cacheSeller of AbcServlet
*
*/
public class CacheSellerClearThread extends Thread {
public void run() {
while (true) {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Here it is clearing the static string field cacheSeller of AbcServlet
AbcServlet.clearCacheSeller();
}
}
}
如果您查看代码,可以发现cacheSeller的值在doGet方法中被读取和修改。所有请求线程都会执行doGet,在此同时CacheSellerClearThread将在每2秒钟清除其值。因此,为了维护cacheSeller值的数据完整性,我使用同步。
我需要一个建议,是否有其他方法可以在clearCacheSeller方法中不使用显式同步,也不在Servlet中应用显式类级锁定的情况下实现这一点(我是指使用任何高级并发API,如原子引用或您可以建议的其他API)。
我已经使用AtomicReference编写了新的实现,请建议,我是否需要在任何地方使用同步。
public class AbcServlet extends HttpServlet {
private static AtomicReference<String> cacheSeller = new AtomicReference<String>();
@Override
public void init() throws ServletException {
super.init();
cacheSeller.set(populateCacheSeller());
}
/**
* As soon as multiple requests are coming doGet is being called
*/
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (cacheSeller.get() == null) {
cacheSeller.compareAndSet(null, populateCacheSeller());
}
resp.getWriter().print(cacheSeller.get());
}
private String populateCacheSeller() {
String fetchItFromSomewhere = "";// some logic to fetch the sting
return fetchItFromSomewhere;
}
public static void clearCacheSeller() {
cacheSeller.set(null);
}
}