我有一个具有多个写入器和一个读取器的系统,每个读取器都在单独的线程中运行.当有工作可用时,写入者通知读取器,读取器阻止,直到得到通知.

在给定写入器数量的情况下,我希望使用无锁实现来通知读取器.每次读取器醒来时,它都会重置通知标志,执行一些工作,并阻止等待更多通知到达. 从本质上讲,我寻找的是AtomicBoolean的类似功能,它具有阻止的能力,直到它的值成为真.

到目前为止,我try 过的是:

  • 我目前的实现使用的是Semaphore.
  • 信号灯在开始时没有许可证.
  • 阅读器阻止了试图获得许可证的行为.
  • 写入器调用Semaphore.release()以通知读取器.
  • 读取器调用Semaphore.drainPermits(),做一些工作,然后再次阻塞Semaphore.acquire.

我不喜欢Semaphore%方法的原因是:

  • 这似乎有点严厉.我只关心第一个到达的通知.我不需要统计收到了多少其他通知.
  • 如果信号量的计数超过Integer.MAX_VALUE,则会抛出异常.这更多的是一个理论问题,而不是实践问题,但仍然不理想.

是否有一个等于AtomicBoolean的数据 struct 能够阻止等待特定值?

或者,有没有一种线程安全的方式来确保Semaphore的许可数量永远不会超过某个值?

推荐答案

BlockingQueue<Singleton>英镑就足以做到这一点.

例如,你会创建一个ArrayBlockingQueue<Singleton>(1),然后你的服务员就会看起来像:

queue.take();

…通知程序将如下所示:

queue.offer(Singleton.INSTANCE)

…使用offer可确保将多个版本组合在一起.

Java相关问答推荐

填写文本字段后锁定PDF

Junit with Mockito for java

Kubernetes的Java客户端检索状态.处于终止状态的Pod的阶段';正在运行';

通过合并Akka Streams中的多个慢源保持订购

嵌入式ActiveMQ Artemis Web控制台加载错误

Spark上下文在向Spark提交数据集时具有内容,但Spark在实际构建它时发现它为空

try 将JSON字符串响应从API转换为映射字符串、对象>;时出错

使用Class.this.field=Value初始化构造函数中的最后一个字段会产生错误,而使用this.field=Value则不会

Java中不兼容的泛型类型

如何使用Criteria Builder处理一对多关系中的空值?

IntelliJ IDEA依赖项工具窗口丢失

JFree Chart从图表中删除边框

为什么我的登录终结点不能被任何请求访问?

在Spring Boot中使用咖啡因进行缓存-根据输出控制缓存

Java递归泛型是否可以被视为继承和重写的语法糖

spring 数据Elastic search 与 spring 启动数据Elastic search 之间的区别是什么?

Maven创建带有特定类的Spring Boot jar和普通jar

URI构造函数错误?

如何调查进程列表中不可见的活跃 MySQL 事务?

如何在Java中调用对象上预定义的接口方法列表?