Exploring Android Thread Priority
Lets start with basic understanding of how scheduling works in Android or Java runtime.
Android Scheduling Basics
The Java runtime supports a very simple, deterministic scheduling algorithm known as fixed priority scheduling.
This algorithm schedules threads based on their priority relative to other runnable threads.
Android’s thread scheduler uses two main factors to determine how threads are scheduled across the entire system: nice values and cgroups.
Nice values
nice values in Android are used as a measure of a thread’s priority. Threads with a higher nice value (i.e., lower priority, as in they are being “nice” to other threads in the system) will run less often than those with lower nice values
Cgroups
The thread control groups(cgroups) are Linux container that are used to manage the allocation of processor time for all threads in one container
Android defines multiple control groups, but the most important ones for applications are Foreground and Background Group. The threads in different control groups gets different amounts of execution on processor. Threads in FG group gets more CPU time than threads in BG group. Threads in BG groups gets roughly 5% of CPU time.
Why we need to set thread priority?
The threads created by application by default have the same priority and cgroup membership as UI thread. As a result they compete on equal terms for processor allocation. Hence an application that creates a lot of background threads may reduce performance of UI thread.
To decouple background threads from control group of UI thread, we need reduce the priority of background threads.
Setting Thread Priorities
Now we know what are thread priorities and that they should be set correctly to ensure app responsiveness. Let’s look at how to set thread priority in Android.
In Android we have two ways to set priority to threads : Thread.setPriority() and Process.setThreadPriority().
Thread.setPriority() contains a value from MIN_PRIORITY(1) to MAX_PRIORITY(10)
The second way to set priorities is to call Process.setThreadPriority(). It supports value from -20 to 19.
Here is the mapping from Thread class priority to Process class Priority
Now we know how to set priority lets look at examples in Android.
Normal Thread
Normal thread by default inherits thread priority of caller thread. So if you create a new thread from main thread it will get same priority as main thread.
To reduce the priority of newly created thread you can use Process.setThreadPriority(priority) at starting of run() method of runnable passed in this thread.
Example :
Handler Thread
Handler thread by default has priority Process.THREAD_PRIORITY_DEFAULT
You can set priority using the other constructor
Example :
Intent Service
Intent service use handler thread to run the background tasks. As we saw above, the handler thread has default priority if used with single param constructor. Intent service use single param constructor for creating handler thread.
Since we don’t have access to handler thread inside intent service, so to set priority you need to call Process.setThreadPriority(priority) at start of onHandleIntent() method.
Example :
Executer Service
ExecuterService implementation likeThreadPoolExecutor accepts thread factory as parameter. Using thread factory we can customise threads it uses. As customisation we can set their priority. Now as explained above we should use Process.setThreadPriority() instead Thread.setPriority() to have more refined access to thread priorities.
So to achieve this in thread factory we can create a customised priority thread factory
Example:
Rx
Schedulers in Rx such as io(), computation(), single() use system property and default values to decide thread priority of their threads. Logic is as follows:
So to set priority for Rx threads we need to set system properties used by these schedulers.
Note: They use Thread class priorities so we need to set Thread class priorities in system property and not Process class priorities
I have also created a sample project containing all the sample examples. https://github.com/anubhav7nov/ThreadPrioritySample
References:
Thank You!!