设计问题:合并发送到处理程序的对象

发布于 2024-10-15 07:55:38 字数 597 浏览 6 评论 0原文

我正在寻找对合并发布到处理程序的可运行对象的设计概念的建议或批评。情况是我有一个后台线程,它生成必须在事件线程上完成的小块工作。每个块都以通常的方式作为 Runnable 发布到 Handler。事实证明,如果其中一个 Runnable 尚未开始执行,则很容易对其进行修改以在其运行时执行其他工作,而不是构造和发布另一个 Runnable。这种工作块的合并比构造另一个 Runnable 更便宜,而且还可以减少后台线程淹没事件队列的问题。

但也存在一些问题。首先,我需要访问传递到事件队列的最后一个 Runnable。据我所知,Handler 和 Looper 都没有提供任何这样的功能,所以我打算在我的后台线程代码中保留对最后发布的 Runnable 的引用。我只是假设维护这样的引用不会在系统中的任何地方引起问题。

更严重的问题是,我必须有某种方法来知道 Runnable 是否已从队列中取出并启动。我计划通过向我的 Runnable 类添加一个标志并在 run() 方法的开头进行设置来处理这个问题。仍然需要进行一些同步,以避免测试标志和更新 Runnable(后台线程)之间的竞争条件,以及在 Runnable 开始执行(事件线程)后设置标志。

有人做过这样的事吗?如果有,你是怎么做到的?我是否忽略了一些我需要处理的事情?

I'm looking for advice or critique of a design concept for coalescing Runnable objects posted to a Handler. The case is that I have a background thread that generates small chunks of work that must be done on the event thread. Each chunk is posted to a Handler as a Runnable in the usual way. It turns out that if one of these Runnables has not started executing, it would be easy to modify it to do additional work when it does run instead of constructing and posting another Runnable. This coalescing of work chunks would be both cheaper than constructing another Runnable and would also cut down on the problem of the background thread flooding the event queue.

There are a couple of problems, though. First, I need to have access to the last Runnable delivered to the event queue. As far as I know, neither Handler nor Looper offer any such function, so I was planning to just keep a reference to the last posted Runnable in my background thread code. I'm just assuming that maintaining a reference like this isn't going to cause problems anywhere in the system.

The more serious issue is that I'd have to have some way of knowing if a Runnable has been taken off the queue and started. I plan to handle that by adding a flag to my Runnable class and setting at the start of the run() method. There would still be some synchronizing necessary to avoid race conditions between testing the flag and updating the Runnable (background thread) and setting the flag once the Runnable starts executing (event thread).

Has anyone done anything like this, and if so, how did you do it? Am I overlooking something that I need to deal with?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尴尬癌患者 2024-10-22 07:55:38

这似乎是一种编写一些令人讨厌的错误的方法。
我有一个程序,经常接收 feed veeeery 并将其发布到多个组件上,它实际上不会造成太大伤害,也没有任何明显的副作用。

如果你真的想接受它(我可能不完全理解你的情况),有一些“工作块”池,其中将存储所有需要的工作和某种工作启动器,不是更容易吗?偶尔启动一个新的 Runnable。
它是这样的:

对于第一个事件,“工作启动器”将可运行的内容发布到处理程序。这个可运行程序要求池给他当前可用的所有工作并处理它,最后它告诉“工作启动者”它已经完成,启动者运行另一个可运行程序,向池请求新工作,等等......
您发布的可运行程序可以是您自己的工作线程可运行程序的子类,以便更轻松地对池进行查询并报告已完成的工作。无需存储标志或更改可运行对象。并且无需处理并发问题(如果您只有 1 个处理程序)

That seems like a way to code some nasty bugs.
I have a program, that receives feed veeeeery often and posts it on multiple components, and it actually doesn't do much harm and doesn't have any visible side effects.

If you really want to go with it (I might not fully understand your situation), wouldn't it be easier, to have some "work chunks" pool, where all the needed work will be stored and some kind of work starter that will launch a new Runnable once in a while.
It goes like this:

With the first event, the "work starter" posts a runnable to a handler. This runnable asks the pool to give him all the work currently available and processes it, at the end it tells the "work starter" that it has finished, starter runs another runnable, that asks the pool for a new work, etc...
The runnable you post can be a subclass of your own worker runnable, to make those queries to the pool and report about finished work easier. No need to store flags, or change runnables. And no need to deal with concurrency problems (if you have only 1 handler that is)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文