- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
数据库中有一些记录在 cId 和 mId 之间有关联,我通过一些复杂的数据库查询获得这些记录。Use Case 是获取 cId & mId 组合对应的 dataId 的完整列表,并推送到 redis。我们从输入的 csv 文件中获取 cId 和 mId 组合到我的批处理作业。文件中会有多条记录对应同一个组合批处理作业配置了 10 个并行线程和一个读取记录的线程。我们想要的只是当线程从文件中读取特定组合时,我们从数据库中获取所有记录并将它们上传到 Redis 以解决 2 个问题:1.数据库命中2. 并发问题,即两个线程不应该根据 cId 和 mId 组合从数据库中获取相同的记录
private static Long DEFAULT_REDIS_OBJECTID = 0L;
public DataObject getDataObject(C cId, M mId) {
String redisListKey = new StringBuilder().append(LIST-).append(cId)
.append("-").append(mId).toString();
if (BooleanUtils.isFalse(redisTemplate.hasKey(redisListKey))) {
pushRedisData(cId, mId, redisListKey);
}
}
Long dataId = redisTemplate.opsForList().leftPop(redisListKey);
if (Objects.isNull(dataId ) || 0L.equals(dataId )) {
// Again creating the key in order to make sure another thread request for this should not shouldn't go in the db as we know we dont have data in db for this combination
redisTemplate.opsForList().leftPush(redisListKey, 0L);
//create a new dataObject and return it
} else {
//Get the dataObject based on dataId and return it
}
public synchronized void pushRedisData(Long cId, Long mId, String redisListKey) {
if (BooleanUtils.isFalse(redisTemplate.hasKey(redisListKey))) {
List<Long> dataToPush = dataService.getDataIdListFromCIdAndMIdCombination(cId,
mId);
if (CollectionUtils.isNotEmpty(dataToPush )) {
redisTemplate.opsForList().leftPushAll(redisListKey, dataToPush );
redisTemplate.expire(redisListKey, 5, TimeUnit.HOURS);
} else {
if (redisTemplate.opsForList().size(redisListKey) == 0) {
redisTemplate.opsForList().leftPush(redisListKey, DEFAULT_REDIS_ITEMID);
}
}
我做了一个synchronized方法把记录push到redis,这样只有一个线程能够把数据发布到key对应的redis,其他线程只是从redis中pop数据。如果在数据库中没有找到任何 cId 和 mId 组合的记录,那么我将在 redis 上创建默认值为 0 的键,这样具有这种组合的线程不应该进行数据库调用。
问题: 当我在文件中执行包含 1000 条记录的批处理作业并且配置了 10 个线程来处理这些记录时,我看到 3-5 个线程获得了已分配给其他线程的重复 dataId threads and object is under process 导致具有重复 dataId 的线程出现 Stalestate 异常。我还发现在前几条记录的作业开始阶段遇到了这个问题。
最佳答案
由于同步泄漏,您遇到了竞争条件。
您尝试同步的方式是有漏洞的,它允许多个线程执行相同的工作。这是你已经注意到的事情。没有原子 block 可以防止两个并发线程执行相同的语句——这里不说锁。
如果您使用相同的对象实例,引入synchronized
方法可能会在本地解决问题,但这不是解决方案。它会阻塞其他并发线程,阻止它们继续进行。
你为什么不通过例如同步利用 Redis 的属性呢?一组?
您可以使用 Redis 集来确保只有一个线程/进程能够通过将特定元素添加到 Redis 集来处理该元素。 Redis 将响应添加该元素是否成功。此信息将帮助您通过检查响应来解决竞争问题。如果该元素可以添加到集合中,那么当前线程是第一个命中您的 dataId
的线程,并且该线程可能会继续进行昂贵的工作(数据库获取,...)。
当向同步集中添加元素失败时,您就知道其他进程已经在做昂贵的工作,您可以继续从缓存中查找数据。您需要注意,尽管另一个线程可能赢得了非阻塞同步,但另一个第一个线程不一定完成填充缓存。然后您可以:
再想想更糟糕的是:WAITING缓存值并阻止导入进程或多次查询昂贵的数据源。您可以针对这两种情况进行优化,但您需要自行决定。
关于redis - 在多线程环境中从 Redis 列表中弹出值会将重复值返回给少数线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49154918/
我在文档中找不到答案,所以我在这里问。 在 Grails 中,当您创建应用程序时,您会默认获得生产、开发等环境。 如果您想为生产构建 WAR,您可以运行以下任一命令: grails war 或者 gr
我们组织的网站正在迁移到 Sitecore CMS,但我们正在努力以某种方式为开发人员 (4)、设计师 (4)、QA 人员 (3)、作者 (10-15) 和批准者 (4-10) 设置环境在他们可以独立
如何在WinCVS中设置CVSROOT环境变量? 最佳答案 简单的回答是:您不需要。 CVSROOT 环境变量被高估了。 CVS(NT) 只会在确定存储库连接字符串的所有其他方法都已用尽时才使用它。人
我最近完成了“learnyouahaskell”一书,现在我想通过构建 yesod 应用程序来应用我所学到的知识。 但是我不确定如何开始。 关于如何设置 yesod 项目似乎有两个选项。一是Stack
在这一章中,我们将讨论创建 C# 编程所需的工具。我们已经提到 C# 是 .Net 框架的一部分,且用于编写 .Net 应用程序。因此,在讨论运行 C# 程序的可用工具之前,让我们先了解一下 C#
运行Ruby 代码需要配置 Ruby 编程语言的环境。本章我们会学习到如何在各个平台上配置安装 Ruby 环境。 各个平台上安装 Ruby 环境 Linux/Unix 上的 Ruby 安装
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我有一个这样的计算(请注意,这只是非常简化的、缩减版的、最小的可重现示例!): computation <- function() # simplified version! { # a lo
我使用环境作为哈希表。键是来自常规文本文档的单词,值是单个整数(某个其他结构的索引)。 当我加载数百万个元素时,更新和查找都变慢了。下面是一些代码来显示行为。 看起来从一开始的行为在 O(n) 中比在
我正在构建一个 R 包并使用 data-raw和 data存储预定义的库 RxODE楷模。这非常有效。 然而,由此产生的.rda文件每代都在变化。某些模型包含 R 环境,并且序列化似乎包含“创建时间”
(不确定问题是否属于这里,所以道歉是为了) 我很喜欢 Sublime Text ,我经常发现 Xcode 缺少一些文本/数据处理的东西。我可能有不止一个问题—— 'Command +/' 注释代码但没
我正在使用 SF2,并且创建了一些有助于项目调试的路由: widget_debug_page: path: /debug/widget/{widgetName} defau
我创建了一个名为 MyDjangoEnv 的 conda 环境。当我尝试使用 source activate MyDjangoEnv 激活它时,出现错误: No such file or direct
有没有办法区分从本地机器运行的包和从 Cordova 应用商店安装的包? 例如,我想像这样设置一个名为“evn”的 JavaScript 变量: if(cordovaLocal){ env = 'de
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我的任务是使用 java 和 mysql 开发一个交互式网站:使用 servlet 检索和处理数据,applet 对数据客户端进行特殊处理,并处理客户端对不同数据 View 的请求。 对于使用 jav
这按预期工作: [dgorur@ted ~]$ env -i env [dgorur@ted ~]$ 这样做: [dgorur@ted ~]$ env -i which date which: no
我想进行非常快速的搜索,看来使用哈希(通过环境)是最好的方法。现在,我得到了一个在环境中运行的示例,但它没有返回我需要的内容。 这是一个例子: a system.time(benchEnv(), g
我想开始开发 OpenACC 程序,我有几个问题要问:是否可以在 AMD gpu 上执行 OpenACC 代码? 如果是这样,我正在寻找适用于 Windows 环境的编译器。我花了将近一个小时什么也没
这可能看起来很奇怪,但是有没有办法制作机器(linux/unix 风格 - 最好是 RHEL)。我需要控制机器的速度以确保代码在非常慢的系统上工作并确定正确的断点(在时间方面)。 我能做到的一种方法是
我是一名优秀的程序员,十分优秀!