我想了解更多关于控制每个Scala actor运行位置的程度。我恰好处于某种特殊情况:需要高反应性,代码的很大一部分是时间关键的,最糟糕的是,我在Android上。考虑到这一点,我的主要目标是:使代码尽可能简单易读。
我理想的想要实现的目标(其中一些听起来不合理/彻头彻尾的愚蠢,请阅读下面的理由)
- 我希望能够在某些特定的,任意相同的线程中响应某些消息,但我不需要阻止它等待消息。
- 我希望在工作线程池上完成大部分处理,理想情况是在Scala actor支持时自动调整大小,同时保证这个处理永远不会在上面的任意线程上进行。
这些要求源于Android的必要性:Android框架使用特殊线程来触摸UI,如果您从另一个线程触摸任何UI对象,您将获得异常。通过这种方式,它强制执行某种线程/锁定模型,这正是我正在努力解决的问题。但无论如何,这就是它的方式:我必须确保我的一些处理,即处理UI对象,正在这个线程上运行,而不是其他,因为框架恼人地说我应该怎么做。 令人讨厌的副作用是,只要此线程处理我的代码,UI停止更新并且我的应用程序停止响应。所以我需要确保这个线程没有被随机选择,因为我可以在一些react {}中使用长期运行的代码,理想情况下它永远不会处理可能由另一个线程完成的事情。
android框架提供了一个名为Handle的类,它实现了某种消息传递 - 你发送一个Runnable,它将在UI线程上运行。如果需要,我可以使用它。每次都会创建一个Runnable使代码混乱 - 可以做的一件事就是将它封装在某个方法中,这样我就可以编写类似的东西了
onUIThread {/ *一些代码* /}
...比新的Runnable(){def run(){}}好得多。另一方面,这基本上就是onUIThread函数将要做的事情,所以我将创建两个闭包 - 然后我必须处理闭包的内存分配细节。我必须这样做,因为每次我分配一个对象时,GC都有机会在Android上运行,通常暂停执行150ms,这会破坏我的用户体验,如果它发生在一个关键的执行路径中。
所以最后:
- 我有没有办法静态地将一个actor与一个线程相关联,这样我就可以拥有一个UI actor,在其中反应{}并始终在UI线程上运行它的代码? / *我知道它本身设计不好,请阅读上面的理由,看看为什么我无法帮助它* /
- 我是否有任何方法可以确保永远不会考虑将此特定线程用于响应{}中的消息?
- 考虑到我的约束,我可以做些什么建议,以获得更好的代码清晰度?
答案 0 :(得分:5)
您可以通过扩展将任务推送到ui线程的IScheduler特征来实现客户调度程序,然后覆盖需要在ui线程上运行的actor的调度程序方法。
有人试过Swing一段时间后我认为它有效: http://scala-programming-language.1934581.n4.nabble.com/scala-Swing-event-thread-actors-td1987246.html
然后让其他演员使用普通的调度程序。
但是我会指出react {}会导致创建一个最终包含在runnable中的闭包。它还使用流控制的异常,这会带来相当大的开销(我不知道Dalvik有多少)。因此,如果GC关闭真的会损害你的应用程序的性能,我怀疑演员会拯救你。