HandlerThread vs Executor - 什么时候比另一个更合适?

ces*_*sar 36 concurrency android

我只是好奇是否有时候我应该选择Executor一个HandlerThread.是否有时候一个优于另一个,或者我真的应该坚持HandlerThread?就我而言,我正在侦听一个ServerSocketfor连接,并在一个单独的线程上处理每个请求Executor.尽管我给出了一个具体的例子,但我真的只是在寻找一个比另一个更合适的案例.但是,我欢迎对我的设计发表评论.

sat*_*ine 49

Executor类功能更强大,可以使用线程池,而每个Handler引用一个线程.执行程序允许您获取所有计划任务并根据需要取消它们.另一方面,处理程序不会回答简单的问题,例如,有多少任务正在等待或者给我一个等待所有等待任务的参考.我相信处理程序更有限的一个原因是因为Android允许您访问它用于UI的主要处理程序,如果您开始取消OS任务,您可能真的搞砸了操作系统.

通常,如果您需要一个线程池或大量电源,请使用Executor.如果您只需要一个漂亮的后台线程来一次运行一个任务,请使用Handler.作为一个例子,当我想查询我的数据库时,我真的只想要一次发生一个查询,我不想生成一个ANR,所以我使用在后台线程上运行的Handler来运行我的查询.

我相信您选择的执行程序听起来很合适,因为您希望同时处理多个传入请求,而Handler一次只能执行一个.

更新:如何创建在后台线程上运行的处理程序:

在你的构造函数或onCreate中写下以下内容,显然你可以将优先级设置为你喜欢的任何内容:

public class MyClass {

    private Handler mBgHandler;

    public MyClass() {
        HandlerThread bgThread = new HandlerThread("My-Background-Handler");
        bgThread.start();
        mBgHandler = new Handler(bgThread.getLooper());
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:当你完成它时,不要忘记退出()或quitSafely()你的HandlerThread否则它将永远等待


cla*_*ker 13

我不会在2011年12月22日的satur9nine的答案中遵循示例代码.

Thread.MIN_PRIOROTY映射到android.os.Process.THREAD_PRIORITY_LOWEST.Quote:

最低可用线程优先级.只有那些真的,真的不想跑,如果发生任何其他事情的人.

我至少会使用android.os.Process.THREAD_PRIORITY_BACKGROUND,如下所示:

HandlerThread bgThread = new HandlerThread("handler name");
Process.setThreadPriority(bgThread.getThreadId(), Process.THREAD_PRIORITY_BACKGROUND);
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
Run Code Online (Sandbox Code Playgroud)

这会为线程分配默认的Android后台优先级.

目前,优先级为Process.THREAD_PRIORITY_BACKGROUND和更低级别的线程通过Linux cgroup共享人为限制的CPU时间,例如,请参见此处.如果后台任务不只是等待I/O但是执行实际计算,我会考虑通过android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE来增加它的优先级,它(当前)将它移出后台cgroup,同时仍然没有严重危及UI和实时活动.

更新: satur9nine的回答在2013年1月至08年间默默修改,不再设置最低优先级.HandlerThread现在隐式具有android.os.Process.THREAD_PRIORITY_BACKGROUND的优先级.这意味着它现在获得默认的后台任务优先级,但仍然限制为消耗人为最大10%的CPU时间以及可能存在的所有其他后台任务.如果不需要,请使用上面的代码,例如

Process.setThreadPriority(bgThread.getThreadId(),
                          Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
Run Code Online (Sandbox Code Playgroud)

将你的后台线程从cgroup中提升出来.