我已經寫了一個名爲AbcServlet.java
Servlet中,在此我有一個Static String field called cacheSeller
。它正在填充在小服務程序的方法init
和doGet
中。它是由一個CacheSellerClearThread.java
清除如下圖所示:通過方法暴露Servlet的靜態字段 - 需要數據完整性
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,如原子參考或任何其他你可以建議。)
我已經寫了新的實現使用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);
}
}
第一,它從來就不是一個好主意,有@ niiraj874u我同意你的servlet類 – niiraj874u
靜態實例變量,但這是我不能改變這是根據設計。 –
你什麼時候創建並啓動線程來清除它?我認爲你知道init方法在其servlet的生命中只會被調用一次 – niiraj874u