【问题标题】:What java structure for a binary semaphore二进制信号量的java结构是什么
【发布时间】:2021-06-28 22:15:54
【问题描述】:

我有:

  • 产生物品的许多线程
  • 通过显示项目来更新 GUI 的单个线程

要点:

  • 制作物品比更新 GUI 快得多
  • 我们可能同时生产许多新产品
  • 每个项目生产后都必须进行一次 GUI 更新
  • 如果生产同时发生,则必须在所有生产之后一次更新。. 无需多次刷新 GUI

我想我正在寻找一些实现二进制信号量的标准结构,其中允许的最大数量为 1,以便工作人员可以调用多个 release() 而不会相互阻塞,如果调用 release() ,那么:

  • 如果 GUI 线程正在休眠 => 它被唤醒
  • 如果 GUI 线程正在执行其例程 => 它必须在结束后重新启动它,然后才能再次进入睡眠状态

代码应如下所示:

[Workers]
.. produce item ..
sem.release()

[GUI Thread]
while(true) {
  sem.acquire()
  .. update gui ..
}

请注意,使用 1 个可用许可证初始化的 Semaphore 不是这种情况的解决方案,因为许多工人同时完成他们的任务应该只释放一个许可证;否则 GUI 线程会运行太多次

【问题讨论】:

  • “如果同时发生”中的“同时”是什么意思?
  • 听起来你在找ReadWriteLock
  • @shmosel 这是一个常见的场景:工人生产一个物品。 Gui开始更新。其他 10 名工人生产 10 件商品。 Gui 完成更新,但必须重新启动其路由一次(并且仅一次)。您能否也与 ReadWriteLock 分享一个解决方案
  • 不清楚“如果 GUI 线程正在执行其路由”应该是什么意思。什么“路由”?除此之外,您是在谈论现实生活中的 GUI 吗?例如,Swing 已经为这项工作设计了SwingWorker。否则,您在谈论“生产项目”,那么BlockingQueue 实现和ConcurrentLinkedQueue 之一都不合适吗?
  • 抱歉打错了。这是“常规”而不是路由。 GUI 线程的例程更新 JTable 行、JTextFields 值并绘制图表。每个工作人员将值生成到并发列表中,有时它是 ConcurrentLinkedQueue,有时它是同步列表。 GUI 例程将读取这些值并指示 swing 如何显示它们。

标签: java concurrency semaphore


【解决方案1】:

使用信号量?

生产者每生产一个项目就将信号量“上调”1。

消费者尽可能地“降低”信号量;像这样:

sema.acquire();  
n = 1;
while (sema.tryAcquire(very short timeout))
    ++n;
// there are now known to be n items available
   

也许在 GUI 'routing' 结束时 tryAcquire 上的相同循环,不管是什么。

这有点过激了。您对一次更新的要求有多严格?你能忍受偶尔得到不止一个吗?

如果它必须只是一个更新,那么就需要有一个双向联锁(即经典的生产者-消费者)。无论您在没有它的情况下做什么,都无法在您决定拥有所有产品后几纳秒内阻止生产者生产“仅再生产一件产品”。为了弥补这个漏洞,需要告知生产者在 GUI 更新时推迟。

【讨论】:

  • 当然,偶尔更新一次以上也没关系。这个解决方案解决了这个问题。无论如何,我想知道是否有一些更具体的标准类来实现同样的目标。
  • 我不知道 - 你必须自己动手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 2020-12-23
  • 1970-01-01
  • 2015-07-03
  • 2011-12-22
  • 2012-10-07
相关资源
最近更新 更多