【发布时间】:2010-09-06 04:55:51
【问题描述】:
我想更多地了解控制每个 Scala 角色运行位置的可能性。我碰巧遇到了一个特殊的情况:需要高反应性,代码的很大一部分是时间关键的,最糟糕的是,我在 Android 上。考虑到这一点,我的主要目标是:使代码尽可能地可读和简单。
我理想中想要达到的目标(其中一些听起来不合理/完全愚蠢,请阅读下面的基本原理)
- 我希望能够在某个特定的、始终相同的任意线程中响应一些消息,但我不需要阻止它等待消息。
- 我希望我的大部分处理都在一个工作线程池上完成,理想情况下可以在 Scala 演员支持的情况下自动调整大小,同时保证这个处理永远不会发生在上面的任意线程上。
这些要求源于 Android 的必要性:Android 框架使用一个特殊的线程来触摸 UI,如果您从另一个线程触摸任何 UI 对象,则会出现异常。通过这种方式,它强制执行某种线程/锁模型,这正是我想要解决的问题。但无论如何,事情就是这样:我必须确保我的一些处理,即处理 UI 对象的内容,在这个线程上运行,而不是在其他线程上运行,因为框架令人讨厌地说我应该这样做。 一个恼人的副作用是,只要这个线程正在处理我的代码,UI 就会停止更新并且我的应用程序停止响应。所以我需要确保这个线程不会被随机选择用于我可以在某些 react{} 中拥有的长时间运行的代码,并且理想情况下它永远不会处理可能由另一个线程完成的事情。
android 框架提供了一个名为 Handle 的类,它实现了某种消息传递——你给它发送一个 Runnable,它就会在 UI 线程上运行。如果需要,我可以使用它。每次都创建一个 Runnable 会使代码严重混乱 - 可以做的一件事是将其封装在某种方法中,以便我可以编写类似
onUIThread { /* 一些代码 */ }
...这比 new Runnable() { def run () {}} 要好得多。另一方面,这基本上就是 onUIThread 函数要做的事情,所以我将创建两个闭包——然后我必须处理闭包的内存分配细节。我必须这样做,因为每次我分配一个对象时,GC 都有机会运行,并且在 Android 上执行通常会暂停 150 毫秒,如果它发生在关键执行路径中,这将破坏我的用户体验。
最后:
- 我有什么方法可以将actor与线程静态关联,这样我就可以拥有一个UIactor,在其中做出react{},并始终让它的代码在UI线程上运行? /* 我知道它本身就是一个糟糕的设计,请阅读上面的理由,看看为什么我忍不住 */
- 我有什么方法可以确保永远不会考虑使用这个特定线程来响应 react{} 中的消息?
- 考虑到我的限制,我可以做些什么来获得更好的代码易读性,有什么建议吗?
【问题讨论】: