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.

Worker thread competing for resources with 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



Thank You!!