java - 线程安全的任务批处理

标签 java google-app-engine thread-safety

我正在使用 appengine 服务器。我预计会收到许多(数十个)非常接近的请求,这将使我的一些数据处于不一致的状态。该数据的清理可以有效地进行批处理 - 例如,最好在数十个请求全部完成后只运行一次清理代码。我不知道到底会有多少请求,也不知道它们的间隔有多近。清理代码运行多次也可以,但必须在最后一次请求之后运行。

减少清理运行次数的最佳方法是什么?

这是我的想法:

public void handleRequest() {
    manipulateData();
    if (memCacheHasCleanupToken()) {
        return; //yay, a cleanup is already scheduled
    } else {
        scheduleDeferredCleanup(5 seconds from now);
        addCleanupTokenToMemCache();
    }
}

...

public void deferredCleanupMethod() {
    removeCleanupTokenFromMemcache();
    cleanupData();
}

我认为这会失败,因为即使某些请求发现内存缓存中有清理 token (HRD 延迟等),cleanupData 也可能会收到过时的数据,因此可能会丢失一些数据在清理中。

所以,我的问题:

  1. 这个总体策略会奏效吗?也许我在数据存储实体上使用事务锁?
  2. 我应该使用什么策略?

最佳答案

您建议的一般策略将会起作用,只要需要清理的数据没有存储在每个实例上(例如,它位于数据存储区或内存缓存中),并且您的 schduleDeferredCleanup 方法使用任务队列。一种优化方法是使用基于任务运行时间间隔的任务名称,以避免在内存缓存 key 过期时安排重复的清理工作。

不过,上述过程中需要注意的一个问题是竞争条件。如上所述,与清理任务同时处理的请求可能会检查内存缓存,观察 token 是否存在,并忽略将清理任务排入队列,而清理任务已经完成,但尚未删除内存缓存 key 。避免这种情况的最简单方法是让内存缓存 key 自行过期,但要在相关任务执行之前。这样,您可以安排重复的清理任务,但决不应该遗漏所需的任务。

关于java - 线程安全的任务批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7956018/

相关文章:

java - 正则表达式 - 禁用同一行的特定子字符串

google-app-engine - datastore.Get 使用祖父 key

.net - .NET System.Net.CookieContainer 线程安全吗?

c++ - 线程安全的 C++ 堆栈

c - 启用禁用中断和线程安全

java - 无法将正确的项目链接到注册表中的正确所有者

java.lang.IllegalArgumentException : Path must not be empty in Picasso 异常

java - 如何使用 web.xml 阻止 IP 地址?

python - 在 python 中使用 IOT 适配器和 google pub/sub api 将 MQTT 与 GCP 集成

mysql - Google 是否不鼓励使用第 3 方 Go 驱动程序来使用云 sql?