I'm just curious about whether there are times in which I should choose an Executor
over a HandlerThread
. Are there times that one is superior over the other, or should I really just stick with the HandlerThread
? In my case, I'm currently listening to a ServerSocket
for connections, and handling each request on a separate thread created by an Executor
. Even though I gave a specific example, I'm really just looking for cases in which one is more appropriate than the other. However, I welcome comments about my design.

- 8,944
- 12
- 46
- 59
2 Answers
The Executor class is more powerful and can use a pool of threads, whereas each Handler references a single thread. The Executor allows you to get all the scheduled tasks and cancel them if you'd like. The Handler on the other hand will not answer simple questions such as, how many tasks are waiting or give me a reference to all waiting tasks. I believe one reason that the Handler is more limited is because Android gives you access to the main Handler it uses for the UI and you could really screw up the OS if you started canceling OS tasks.
In general if you need a pool of threads or lots of power use the Executor. If you just need a nice background thread to run one task at a time use a Handler. As an example when I want to query my database I only really want one query to occur at a time and I don't want to generate an ANR so I use a Handler running on a background thread to run my queries.
I believe your choice of executor sounds appropriate since you want to handle multiple incoming requests simultaneously and a Handler can only do one at a time.
UPDATE: How to create a Handler that runs on a background thread:
In your constructor or onCreate write the following, obviously you can set the priority to whatever you like:
public class MyClass {
private Handler mBgHandler;
public MyClass() {
HandlerThread bgThread = new HandlerThread("My-Background-Handler");
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
}
}
UPDATE: Don't forget to quit() or quitSafely() your HandlerThread when you are done with it otherwise it will remain waiting forever

- 13,927
- 5
- 80
- 123
-
HandlerThread is what you use to get a Handler that runs on a background thread. The user engineer will interact with the HandlerThread much. I have updated my answer to show how you create a Handler using a HandlerThread. – satur9nine Dec 22 '11 at 01:28
-
@satur9nine Regarding your following remark: _I believe on reason that the Handler is more limited because Android gives you access to the Main thread and you could really screw up the OS if you started canceling OS tasks._ Have you tried Handler.getLooper().getThread()? It's supposed to give you access to the underlying Thread. – class stacker Jan 08 '13 at 09:59
-
What I mean is Android gives you access to the Handler that is used to schedule essential internal tasks on the main thread. If you were to unschedule or otherwise modify these internal tasks that would mess up the Android OS. – satur9nine Feb 18 '13 at 19:04
-
I too find it to be very limiting since I am unable to get messagequeue out of looper. I am getting a huge wait time and I wanted to see what was the issue but no luck. – Harshit Bangar Nov 01 '15 at 15:54
I wouldn't follow the sample code in satur9nine's answer as of 2011-Dec-22.
Thread.MIN_PRIOROTY is mapped to android.os.Process.THREAD_PRIORITY_LOWEST. Quote:
Lowest available thread priority. Only for those who really, really don't want to run if anything else is happening.
I would at least use android.os.Process.THREAD_PRIORITY_BACKGROUND, like so:
HandlerThread bgThread = new HandlerThread("handler name");
Process.setThreadPriority(bgThread.getThreadId(), Process.THREAD_PRIORITY_BACKGROUND);
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
This assigns the default Android background priority to the thread.
Currently, threads of priority Process.THREAD_PRIORITY_BACKGROUND and lower share an artificially limited amount of CPU time by means of a Linux cgroup, see for example here. If a background task does not just wait for I/O but performs real computations, I'd consider increasing its priority by android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE which (currently) moves it out of the background cgroup while still not substantially endangering UI and real time activities.
Update: satur9nine's answer was silently revised on 2013-Jan-08 to not set the lowest possible priority any more. The HandlerThread will now implicitly have a priority of android.os.Process.THREAD_PRIORITY_BACKGROUND. This means that it now gets the default background task priority but it is still limited to consume an artificial maximum of 10% CPU time along with all another background tasks which may exist. If that's not desired, use my code above e.g. with
Process.setThreadPriority(bgThread.getThreadId(),
Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
to lift your background thread out of the cgroup.

- 5,357
- 2
- 32
- 65
-
with that sequence of commands, `getThreadId` returns -1 and that breaks `Process.setThreadPriority()`. I'm missing something really obvious, probably better quit coding today – superjos Sep 19 '18 at 19:53
-
@superjos Check the API documentation of the Android version in question, and find out whether `Process.setThreadPriority()` is not allowed, or `new HandlerThread()` fails. Then, eliminate the problem. – class stacker Sep 25 '18 at 17:09
-
thanks for your reply @class-stacker. I don't get it completely, could you reason about it with me? `new HandlerThread()` call is *not* failing for me. But `bgThread.getThreadId()` returns -1. When that value is passed to `Process.setThreadPriority()` it causes it to throw. I've checked docs (and posts), there are many examples where `setThreadPriority` is used. Do you know more about it? – superjos Sep 26 '18 at 10:21
-
@superjos Post a question which contains the relevant part of your code and drop me a comment with the link to it? – class stacker Sep 27 '18 at 17:16