I've got a system with many writers and a single reader, each running in a separate thread. The writers notify the reader when work is available, and the reader blocks until it is notified.

Given the number of writers, I want to use a lock-free implementation to notify the reader. Every time the reader wakes up, it resets the notification flag, does some work, and blocks waiting for more notifications to arrive. Essentially I'm looking for the equivalent of an AtomicBoolean with an ability to block until its value becomes true.

What I've tried so far:

  • My current implementation uses a Semaphore.
  • The semaphore starts out with no permits.
  • The reader blocks trying to acquire a permit.
  • Writers invoke Semaphore.release() in order to notify the reader.
  • The reader invokes Semaphore.drainPermits(), does some work, and blocks again on Semaphore.acquire.

What I don't like about the Semaphore approach:

  • It seems a bit heavy-handed. I only care about about the first notification arriving. I don't need to keep a count of how many other notifications came in.
  • Semaphores throw an exception if their count surpasses Integer.MAX_VALUE. This is more of a theoretical problem than practical but still not ideal.

Is there a data structure that is equivalent to AtomicBoolean with an ability to block waiting on a particular value?

Alternatively, is there a thread-safe manner to ensure that Semaphore's number of permits never surpass a certain value?

推荐答案

BlockingQueue<Singleton> would do this adequately.

You would create, for example, an ArrayBlockingQueue<Singleton>(1), and then your waiter would look like:

queue.take();

… and the notifier would look like:

queue.offer(Singleton.INSTANCE)

… with the use of offer ensuring that multiple releases are combined together.

Java相关问答推荐

Selenium Java:无法访问IFRAME内部的元素

在URL类图中表示Java swing类

如果给定层次 struct 级别,如何从其预序穿越构造n元树

当我用OkHttpClient重写shouldInterceptRequest来发布数据时,Android WebView正在以纯HTML加载URL内容

无法传递消费者<;>;实例

使用java访问具体子类特定方法的最佳方法是什么?

Hibernate 6支持Joda DateTime吗?

为什么一个Test的instance?& gt;在构造函数中接受非空对象?

Com.example.service.QuestionService中的构造函数的参数0需要找不到的类型为';com.example.Dao.QuestionDao;的Bean

try 判断可选参数是否为空时出现空类型安全警告

在Eclipse中数组的可空性

如何从日志(log)行中删除包名称?

在Java中将int[]矩阵添加到ArrayList中,但出现错误

允许同时执行两个方法,但不能同时执行这两个方法

使用While循环打印素数,无法正常工作

如何在@CsvSource中传递空格作为值

Android应用程序为错误的显示类型 Select 尺寸文件

如何在运行docker的应用程序中获取指定的配置文件

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

在外部类和内部类之间,当调用外部类内部或外部的主方法时,它们的静态初始化程序的运行顺序不同