如何等待数据缓存更新,而又不影响其他缓存调用

我有一个中央数据缓存,该缓存由许多在SQL数据库上运行查询的线程更新。还有一种机制可以检查何时最后一次检索到数据高速缓存中的每个特定项(Mydata),并在达到某个时间阈值时(即,如果尚未检索到数据)关闭相应的线程。最后30分钟)。可以使用这种机制来尝试减少对数据库的需求并最大程度地减少长时间运行的查询。

还有许多线程从缓存中获取数据,因此,问题在于,即使不再更新特定项(Mydata),线程也可能会在某个时候请求它。发生这种情况时,将检查相关线程是否正在运行,如果没有运行,则重新启动,如下所示...

private static HashMap<String,MyData> dataMap = new HashMap<>(10);

public static MyData getMyData(String identifier) {
  if(!MyThreadManager.getInstance().isRunning(identifier)) {
     LOG.info("Thread with identifier={} possibly stopped,restarting.",identifier);
     MyThreadManager.getInstance().startThread(identifier);
  }
  MyData myData= null;
  if(dataMap.containsKey(identifier)) {
     myData= dataMap.get(identifier);
  } else {
     LOG.debug("No data found in dataMap for identifier={},thread possibly terminated. Restarting.",identifier);
  }
  return myData;
}

...该机制本身运行良好,但是冒着这样的风险,即在运行dataMap.get(identifier)时,它可能仍只包含myData的“过时”版本(因为重新启动的线程)可能仍在处理中)。但是,我想保证返回的数据已经更新。为此,我可以在重新启动线程一秒钟后添加一个睡眠计时器,这应该足以让线程在运行dataMap之前更新dataMap.get(identifier)中的数据。

if(!MyThreadManager.getInstance().isRunning(identifier)) {
  LOG.info("Thread with identifier={} possibly stopped,identifier);
  MyThreadManager.getInstance().startThread(identifier);
  try {
        Thread.sleep(1000L);
    } catch (Exception e) {
        LOG.error(e.getMessage());
    }
}

此实现的最大问题是,它可能会对尝试检索信息的任何其他线程产生负面影响。

问题:在线程重新启动的情况下,我如何实现线程安全/非锁定方式来“等待”更新缓存,同时又不影响使用同一数据缓存的其他线程。

gaohhxx2009 回答:如何等待数据缓存更新,而又不影响其他缓存调用

好,所以进行了一些测试。如果getMyData方法是从线程内调用的...

public class MyRunnable implements Runnable {

  private String identifier = "";

  public MyRunnable(String identifier) {
    this.identifier = identifier;
  }

  @Override
  public void run() {
    MyData myData = MyDataManager.getInstance().getMyData(identifier)
    System.out.println(String.format("Data retrieved : %s",myData.toString()));
  }

}

...然后引入Thread.sleep(1000L);重新启动数据收集线程将不会对任何其他并发线程产生影响。除非当然要加上synchronized方法关键字,否则该关键字将强制一次避免竞争情况。

由于这些请求的最终来源是由Servlet容器处理的HTTP请求,因此上述方法可以正常工作。由于servlet允许JVM在单独的Java线程中处理每个请求。因此,对getMyData方法的每次调用都是在其自己的线程上进行的,任何“等待”都将影响其他请求。

本文链接:https://www.f2er.com/3154465.html

大家都在问