首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确保写入时线程执行顺序必须在读取之前发生

确保写入时线程执行顺序必须在读取之前发生
EN

Software Engineering用户
提问于 2019-07-11 20:42:06
回答 3查看 270关注 0票数 0

我目前正在设计一个具有以下结构的服务器:

  • 从网络接收数据的TCP线程池。
  • 包含这些请求的队列。
  • 一个固定大小的工作线程池,它接收来自队列的请求,并在读取ConcurrentHashMap的地方执行一些工作,并分析结果。工作完成后,结果将被发布到写队列中。
  • 写队列存储ConcurrentHashMap的写请求
  • 一个固定大小的写线程池,它接收来自写池的请求并将它们写入ConcurrentHashMap

服务器约束:

  • 对于ConcurrentHashMap中的特定条目,写入将在读取发送到网络之前几秒钟发布到网络。线程绝不能允许在写入之前对读进行调度。

到目前为止,我的想法:

  • 首先,我希望3-5秒左右的时间是一个足够大的开端,可以在阅读之前完成。
  • 将写入线程设置为高优先级,将读线程设置为低优先级。
  • 读可以检查最后的写入时间,如果足够大(就像几分钟或几个小时前),它知道忽略最后一次写入,因为它已经过时了。然而,它知道自己无法做出明智的决定。如果条目过时,我可以让线程重试两次,但这感觉很笨拙。
  • 添加了写入队列,以便TCP池可以直接将写入队列(写入请求不需要由工作池处理)而不是作业队列,而不是在读取请求放在工作线程队列中时,然后将一些日志信息发送到写入队列。在工人池之后

是否有任何方法可以确保在写之前阅读的可能性很低,或者我已经采取了足够的预防措施?我应该使用读重试机制吗?

另外,是否实际需要写队列,或者我是否可以更一般地使用工作线程来处理写入?写订单并不重要。

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2019-07-12 12:34:00

别浪费时间。在分布式系统中,它们很容易处理,并且容易出错,特别是因为您需要同步时钟和处理延迟。相反,使用版本号。对于每个写入请求,增加数据上的版本号;对于每个读取请求,发送一个版本号以有条件地执行请求,如果读取请求的版本号与资源的当前版本不匹配(或者,如果您的应用程序可以容忍从未来版本读取,则放松匹配条件,使其不匹配),然后拒绝读取请求(请求客户端可以等待几秒钟并重新发送读取请求),或者将其放回读队列并等待适当的写入请求到达。

为了获得额外的可靠性,读取队列可以是一个优先级队列。版本号是优先级,如果优先级队列的前端(版本号最低的项)高于资源的当前版本,那么读线程应该阻塞,直到写线程由于写事件而唤醒它,或者被一个队列唤醒到比队列中的任何其他条目都有较低版本号的读队列(即,它被插入到优先级队列的前面)。

票数 1
EN

Software Engineering用户

发布于 2019-07-11 21:16:39

我不完全理解您的应用程序做了什么,但您的关注和方法似乎是不存在的。

  • 不要弄乱线程优先级,这些都不会给你带来任何好处。
  • 如果您不希望以其他方式进行读写,只需锁定队列对象即可。
  • 在队列中查找什么都没有的读线程并不是一件坏事。试图控制不同线程的运行顺序是没有意义的,并且违背了线程的目的。
  • 不要在锁内工作,只在使用共享资源时锁定,即写入队列或从队列读取。
  • 在再次寻找新项目之前,将读线程休眠一段时间。
票数 2
EN

Software Engineering用户

发布于 2019-07-12 12:05:08

首先,我希望3-5秒左右的时间是一个足够大的开端,可以在阅读之前完成。

假设这样的事情真的是个坏主意。您应该编写代码来处理这样一个事实,即读取可能首先出现。

因此,如果数据陈旧,您希望read操作等到更新后再执行,对吗?您可能需要使用条件对象。如果数据陈旧,则创建/重置一个条件对象,在更新数据时,写入操作将发出该条件对象的信号。

让线程进入睡眠状态是可行的,但也有一些权衡。例如,它睡多长时间?如果您的睡眠太短,线程只会占用CPU时间,什么也不做。如果您的睡眠时间过长,则应用程序的响应性较差。

使用锁、信号量或条件对象编写代码更简单,响应更快(读取操作只会阻塞,直到有有用的事情可做)。

另外,请参阅实践中的Java并发一书。并发是很难得到正确的,这本书讨论了许多意想不到的问题,以及如何正确地做所有这些事情,包括如何测试它!

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/394569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档