gpt4 book ai didi

java - 通过方法暴露的 Servlet 静态字段——需要数据完整性

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:24:39 24 4
gpt4 key购买 nike

我写了一个名为 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();
}
}
}

如果您查看代码,会在 doGet 方法中读取和修改 cacheSeller 值。所有请求线程都将执行 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);
}
}

最佳答案

我建议使用 Executors框架。

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
AbcServlet.clearCacheSeller();
}
}, 2L,2L,TimeUnit.SECONDS);

并且在你的doGet中,只同步初始化:

 @Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String localCacheSeller = cacheSeller;
if (cacheSeller == null) {
synchronized (this.getClass()) {
if (cacheSeller == null) { //need this because cacheSeller may already have been initialized while we waited
cacheSeller = populateCacheSeller();
localCacheSeller = cacheSeller; //because the executor may clear it after we initialized
}
}
}
}

关于java - 通过方法暴露的 Servlet 静态字段——需要数据完整性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23357005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com