【问题标题】:Multithreaded Observer多线程观察者
【发布时间】:2019-05-10 09:30:59
【问题描述】:

我正在编写一种多线程观察器,但遇到了一些设计问题。

假设我有某种线程池,其中包含要在数据集上执行的任务队列。其中一些是只读数据,另一些则覆盖它们。

在数据发生变化后,我想执行 notifyall(),以便观察者可以 update() 他们的状态。

执行 update() 任务的线程,我希望它们来自不同的第二个线程池。

还有一个问题:在第一个任务队列的另一个函数开始修改数据之前,如何强制所有 update() 线程执行更新操作?

我正在考虑将锁传递给另一个特定线程。

【问题讨论】:

  • 欢迎来到 StackOverflow。如果您用您正在使用的语言(可能还有环境)标记它并发布您已经尝试过的代码,它将帮助社区回答您的问题。看看stackoverflow.com/help/how-to-ask
  • 听起来是个坏主意。通常“迫使所有其他线程采取行动”相当于“如果出现任何问题,这将成为人质”。
  • 好的,那么解决方案是什么?确保所有 update() 操作在另一个任务开始修改数据之前执行?顺便说一句,还没有代码,只是项目设计。

标签: multithreading locking threadpool observer-pattern


【解决方案1】:

如果可以,请避免使用锁。这将破坏让多个线程并行工作的目的。如果您需要在另一个线程上调用更新,因为您的框架(例如 GUI 线程)要求您这样做,锁将导致 UI 线程阻塞并会影响您的性能。

具体解决方案将取决于具体情况。你需要给出一个具体的例子,才能给出具体的解决方案。

最好的方法是根本不使用共享对象。让一个线程将不可变事件发布到另一个线程可以根据这些事件读取和更新的队列。

如果需要使用共享对象,为了能够在某个时间点读取对象的状态,可以使用Memento创建可以从第二个线程读取的对象的快照.

如果您需要从第二个线程获取所有更改,您可以保留数据对象中的更改历史记录,以便udpate() 线程可以跟踪它的位置,并且可以在收到更改通知时读取新更改.

如果您不需要历史记录,只需保留最后的更改。更新线程可能会跳过一些更改,但最终它会在处理最后一个线程时与数据保持一致。您正在使用多线程,因此无法始终保持一致。

查看this 文章。 LMAX 团队使用不同的线程,只有一个线程用于他们的 BusinessLogic。一个线程接收事件并将它们放在缓冲区中。另一个线程,具有 EventProcessorBusinessLogic 线程将它们拾取并处理它们。他们的解决方案适用于您有一个写入器多个读取器并且每个读取器都可以跟踪它在缓冲区中的位置的情况。在你的情况下,如果你只有两个线程,你可以做这样的事情。

您还可以使用Actor model,其中有多个并发参与者通过在它们之间发送消息来协同工作。

【讨论】:

    猜你喜欢
    • 2012-02-03
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多